Skip to content

Latest commit

 

History

History
145 lines (117 loc) · 5.36 KB

File metadata and controls

145 lines (117 loc) · 5.36 KB

Validation

Explanatory documentation only. Validation shown here is pure, deterministic, non-consuming, and non-executing. It is not a replay store.

What problem does this example address?

This example shows how a Host validates Phase 7 Authorization evidence against expectations retained independently of the submitted Authorization and final Consumption Binding.

Why this flow?

An artifact cannot be allowed to describe its own trust roots. Independent expectations, the genuine Host boundary, and explicit time let the validator reconstruct exact binding equality without mutation, I/O, reservation, Consumption, or Execution.

Architecture diagram

flowchart LR
    A["Submitted Phase7Authorization"] --> V["Phase7AuthorizationValidator"]
    B["Submitted final Consumption Binding"] --> V
    C["Independent Host expectations"] --> V
    K["Genuine Host boundary"] --> V
    T["Explicit validation time"] --> V
    V --> S["Success reference"]
    V --> F["Privacy-safe failure"]
    S --> H["Future Host atomic Consumption"]
Loading

Sequence diagram

sequenceDiagram
    participant Host
    participant Validator as Phase7AuthorizationValidator
    participant Store as Host Consumption store
    participant Tool as Host executor

    Host->>Host: load independently retained expectations
    Host->>Validator: Authorization + final binding + context + boundary + time
    Validator-->>Host: successful Reference or stable Failure
    Note over Validator: no mutation, I/O, reservation, or Consumption
    Host->>Store: atomically consume reconstructed binding
    Store-->>Host: success exactly once
    Host->>Tool: execute outside SecureToolKit
Loading

Minimal Swift snippets

The context is created from Host-retained values, not by copying values from a submitted artifact at validation time.

import SecureToolKitCore

let phase7Context = Phase7AuthorizationValidationContext(
    frozenContext: phase6ValidationContext,
    expectedRequirement: retainedRequirement,
    expectedChallengeID: retainedChallengeID,
    expectedConfirmationID: retainedConfirmationID,
    expectedChallengeBinding: retainedChallengeBinding,
    expectedArtifactBinding: retainedArtifactBinding,
    expectedPresentationEvidence: retainedPresentationEvidence,
    expectedConfirmationAuthorityEvidence: retainedAuthorityEvidence,
    expectedHostAuthorityDomain: retainedHostAuthority
)

let result = Phase7AuthorizationValidator.validate(
    authorization: submittedAuthorization,
    submittedConsumptionBinding: submittedConsumptionBinding,
    context: phase7Context,
    hostCapabilityBoundary: hostBoundary,
    validationTime: explicitValidationTime
)

Success and failure are mutually exclusive:

switch result.outcome {
case .successful:
    guard let reference = result.reference, result.failure == nil else {
        preconditionFailure("invalid controlled result shape")
    }
    // `reference.consumptionBinding` is evidence for the Host's future
    // atomic store. It is not itself Consumption or Execution.

case .failed:
    guard let failure = result.failure, result.reference == nil else {
        preconditionFailure("invalid controlled result shape")
    }
    // Use only the stable reason, safe field, and optional public limit.
    handlePrivacySafeFailure(failure)
}

handlePrivacySafeFailure is Host application code. It must not log rejected raw values, prompts, credentials, or sensitive tool arguments.

Expected lifecycle

  1. The Host retains expected identities and bindings as each controlled transition succeeds.
  2. The Host receives a submitted Authorization and final binding.
  3. The Host constructs a non-authoritative validation context from retained expectations.
  4. The Host supplies the genuine boundary and an explicit validation time.
  5. The validator independently reconstructs and compares the complete binding.
  6. Success returns exactly one reference; failure returns exactly one safe failure.
  7. Repeating validation with equal inputs returns an equal result and consumes nothing.
  8. The Host separately performs atomic single-use Consumption before Execution.

Threats prevented

  • Same-ID/different-content Authorization substitution rejects.
  • Challenge, Artifact, presentation, authority, or policy mutation rejects.
  • Subject, tenant, session, delegation, and Host boundary substitution rejects.
  • Capability or resource scope change rejects exact equality.
  • Expired Authorization or confirmation rejects at explicit boundary times.
  • A mismatched final Consumption Binding rejects before Host Consumption.

Validation alone does not prevent a valid artifact from being submitted twice. The Host's atomic store must enforce single use.

Common mistakes

  • Deriving the expected context from the submitted artifact.
  • Treating .successful as Consumption or permission to execute.
  • Reading ambient time instead of supplying an explicit trusted Host value.
  • Ignoring the submitted final binding.
  • Logging raw rejected values alongside a safe failure.
  • Assuming repeated validation reserves a replay identity.

Related documentation