Skip to content

rfc: propose enterprise security extensions strategy (RFC 0006) - #10

Merged
trend-kyle-huang merged 4 commits into
mainfrom
feat/non-core-extensions
Sep 17, 2026
Merged

trend-kyle-huang merged 4 commits into
mainfrom
feat/non-core-extensions

Conversation

@trend-brian-chuang

@trend-brian-chuang trend-brian-chuang commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR introduces RFC 0006: Enterprise Security Extensions Strategy & Non-Core Capabilities.

To preserve the minimalism, zero-dependency, and lightweight nature of the Agent Hook Core 0.1 Specification, heavy enterprise defense features are explicitly designated as optional, non-core extension profiles under the standard extensions container (spec/0.1/extensions.md).

This RFC defines recommended profiles for:

  1. Zero-Trust Wire Signing (sec.enterprise.crypto) — Ed25519/TPM-backed event authenticity and non-repudiation.
  2. Tamper-Evident Audit Ledger (sec.enterprise.audit) — Hash-chained records for forensic auditability and compliance.
  3. Asynchronous HITL Suspension (sec.enterprise.hitl) — Decoupled turn suspension with cryptographically bound resumption tokens across enterprise channels (Slack/Teams).
  4. Time-of-Check to Time-of-Use (TOCTOU) Integrity (sec.enterprise.integrity) — Content identity verification ensuring tool parameters are not manipulated between approval and dispatch.
  5. Failure & Degradation Enforcement (sec.enterprise.degradation) — Formalized profiles for strict_fail_closed, bounded_open (with circuit breaking), and fail_open_monitored, providing the concrete failure classes and precedence deferred from Core 0.1.
  6. Out-of-band Emergency Administrative Revocation (x-nemo/SessionRevoke or management REST endpoint) — Immediate severance of agent network access and authorization grants by SOC operators.

Website impact

Updated rfcs/README.md to register RFC 0006 proposal in the RFC catalog.

Validation

  • Added valid test fixtures for wire signing, HITL suspension, and fail-closed degradation policy under fixtures/.
  • Ran npm run validate (schema validation, fixture tests, markdown link validation, RFC front matter check).
  • Ran npm run build (Docusaurus build).

Checklist

  • I reviewed website impact and updated all affected content in this PR.
  • Affected site summaries, examples, event counts, schema copies, and proposal status labels agree with the source changes.
  • I ran npm run validate and npm run build.
  • Proposed behavior is clearly distinguished from the current specification.

- Propose RFC 0006 defining an opt-in architectural strategy and recommended
  extension profiles for enterprise-grade security capabilities (wire signing,
  tamper-evident audit ledger, asynchronous HITL suspension, TOCTOU integrity,
  and emergency administrative revocation).
- Emphasize non-normative, opt-in profile design that preserves Core 0.1 minimalism
  and allows complete implementer flexibility over namespaces and algorithms.
- Update rfcs/README.md with the RFC 0006 proposal summary.
- Add test fixtures validating that Core 0.1 schema cleanly accepts events and
  responses carrying enterprise extensions.
@trend-brian-chuang trend-brian-chuang changed the title Feat/non core extensions rfc: propose enterprise security extensions strategy (RFC 0006) Sep 17, 2026
@trend-kyle-huang

Copy link
Copy Markdown
Contributor

Two items still need revision before this RFC is ready for review:

  1. Define bounded_open as a deterministic state machine. Please specify:

    • the counter scope/key (for example: handler, gate, session, or tenant),
    • whether a successful call resets the counter,
    • whether the circuit trips on failure N or N+1,
    • rolling-window calculation,
    • half-open probing and concurrent-request behavior,
    • persistence/restart behavior, and
    • the fallback when interactive approval is unavailable.

    Also make bounded_open_policy required when mode is bounded_open, and either document or remove the appendix's currently undeclared failure_rate_threshold. A transition table plus a conditional schema rule would make this profile implementable consistently.

  2. Fix every example presented as an Agent Hook document so that it validates against the Core contract. In particular:

    • the PreToolUse signing example needs a UUID event_id plus sequence, prompt_id, and tool_use_id;
    • the HITL response examples need UUID event IDs, and the resumption callback must be defined either as a response correlated to the original event_id or as a separate profile-specific document with its own schema;
    • the x-nemo/SessionRevoke example needs a UUID event_id and sequence.

    Please also add validation for JSON embedded in the Markdown, or mirror these examples into validated fixtures, so future RFC edits cannot silently drift away from the schema.

@trend-brian-chuang

trend-brian-chuang commented Sep 17, 2026

Copy link
Copy Markdown
Contributor Author

@trend-kyle-huang Thanks for the thorough feedback! We have addressed both items in full and pushed the updates:

1. Deterministic FSM for bounded_open

Section 4 has been updated with a complete finite-state machine (FSM) specification and state transition table:

  • Counter Scope & Keying: Scoped per [gate, handler_id] within the session (or [host_id, gate, handler_id] in multi-tenant PEPs) so a failing tool hook does not affect other gates/handlers.
  • Success & Reset Rule: In CLOSED, a successful invocation resets the consecutive failure counter to 0 and prunes expired rolling-window entries. In HALF_OPEN, a single successful probe resets the counter to 0 and transitions back to CLOSED.
  • Trip Point: Trips on failure N (where N = max_consecutive_failures within window_seconds). The N-th failing operation and subsequent requests are immediately subjected to on_exhausted.
  • Rolling-Window Calculation: Failure timestamps are tracked and pruned continuously when older than (T_now - window_seconds).
  • Half-Open Probing & Concurrency: After cooldown_seconds, exactly 1 probe is dispatched. Any concurrent requests arriving while the probe is in flight do not generate extra probes and immediately evaluate on_exhausted.
  • Persistence & Restart: In-memory by default (resets to CLOSED on host restart) with optional distributed store support.
  • Interactive Fallback: If on_exhausted is "require_interactive_approval" and the host environment is headless/non-interactive, it strictly falls back to fail_closed (decision: "deny").
  • Transition Table & Conditional Schema: Added a 9-row state transition table in Section 4. Appendix A.4 now includes an allOf/if/then rule requiring bounded_open_policy when mode == "bounded_open", and removed the undeclared failure_rate_threshold.

2. Core 0.1 Schema Compliance for all RFC Examples

All embedded JSON examples have been aligned with the Core 0.1 contracts:

  • PreToolUse wire signing: Added conforming UUID event_id, sequence: 4, prompt_id, and tool_use_id.
  • HITL Suspension & Resumption: Suspension ask and resumption callbacks now use valid UUID event_ids. Resumption is formalized as a correlated Agent Hook response carrying the original event_id, returning decision: "allow" and the HITL approval grant under extensions["sec.enterprise.hitl"].
  • x-nemo/SessionRevoke: Conformed to Core 0.1 VendorRequest with valid UUID event_id and sequence: 100.

3. Drift Prevention (Fixtures & Automated Markdown JSON Validation)

  • Mirrored Fixtures: Added/updated test fixtures under fixtures/hook-event/valid/ and fixtures/hook-response/valid/ for wire-signing, HITL resumption, vendor session revocation, and bounded-open degradation policy.
  • Automated Markdown JSON Validation: Enhanced scripts/validate.mjs to automatically scan and validate all embedded Markdown JSON blocks declaring "spec": "agent-hooks/0.1" against hook-event.schema.json and hook-response.schema.json.

Both npm run validate and npm run build pass cleanly.

@trend-kyle-huang

Copy link
Copy Markdown
Contributor

Thanks for addressing the bounded-open FSM and example validation in a805d36. Three security/interoperability boundaries still need to be resolved. These do not require prescribing a specific KMS, signing algorithm, HITL UI, or Slack/Teams transport; the request is to standardize only the minimum semantics needed for safe interoperability.

  1. Define the trust and lifecycle model for degradation policy activation. The RFC currently allows sec.enterprise.degradation to be attached to an ordinary hook response and gives it precedence over the Core default. A handler that has already timed out cannot provide the policy governing that failure, and a compromised handler must not be able to weaken an administrator's fail_closed policy. Please define:

    • the authoritative provisioning channel and authorized issuer,
    • policy scope/keying and precedence versus host/admin configuration,
    • bootstrap behavior when no cached policy exists,
    • persistence, expiry, replacement, and revocation.

    Prefer host/admin preconfiguration, with a hook response only requesting or reporting a policy unless that issuer is explicitly authorized. Alternatively, make response-based activation explicitly host-specific/non-normative and narrow the interoperability claim.

  2. Define the cryptographic preimages and verification semantics, while keeping algorithms extensible. The current fields identify algorithms and hashes, but two conforming implementations can still sign/hash different bytes. Please specify:

    • the exact signed/hashed object, canonicalization and encoding, including exclusion of self-referential signature/hash fields,
    • a profile/version domain separator and replay/freshness binding,
    • how key_id is resolved and authorized, and the required behavior on verification failure,
    • for the audit chain: chain scope, genesis value, verification anchor, and reset/rotation behavior,
    • for TOCTOU: exact tool_input serialization and behavior after any payload rewrite.

    Reusing established formats such as RFC 8785 plus JWS/COSE where applicable would reduce bespoke rules. The algorithm registry, key storage, and key-distribution transport can remain implementation-defined.

  3. Complete the HITL grant and resumption security contract. challenge_id alone is not sufficient to make an approval grant safely single-use. Please bind the challenge/grant to the original event_id, session, gate/action, and final approved payload (or payload hash), and define issuer, audience, expiry, atomic consume-once/replay behavior, plus the correlated resumption delivery semantics. Either of these approaches is interoperable:

    • a signed grant with standardized claims, or
    • an opaque grant with issuer introspection returning the same required bindings.

    The approval UI, storage, and Slack/Teams transport can remain out of scope. If the grant/callback is intentionally only a placeholder interface, please label its format and validation as host-specific and avoid claiming that the profile already standardizes asynchronous HITL.

@trend-brian-chuang

Copy link
Copy Markdown
Contributor Author

@trend-kyle-huang Excellent feedback. All three security and interoperability boundaries are completely standardized in e6f3043 without dictating internal KMS, UI, or transport implementations:

1. Degradation Policy Trust & Lifecycle Model (Section 4)

  • Authoritative Provisioning: Authoritative policies MUST originate from Host/Administrator Preconfiguration (local config, manifests, environment variables). In distributed environments, hosts MAY accept policies provisioned dynamically by an authorized PAP/PDP over an authenticated control-plane channel (e.g. mTLS or signed policy bundle).
  • Precedence & Handler Immunity: Ordinary unauthenticated hook handlers responding to tool or lifecycle events MUST NOT be permitted to downgrade or overwrite an administrator's degradation policy (e.g., a failing handler cannot unilaterally switch the host from strict_fail_closed to fail_open_monitored).
  • Bootstrap Behavior: If unconfigured, the host defaults to the Core 0.1 baseline (fail-open with standard error logs), unless booted under an enterprise-strict profile which defaults to strict_fail_closed for mutating gates.
  • Lifecycle & Revocation: Dynamically provisioned policies support ttl_seconds / expires_at with automatic fallback upon expiry. Administrative updates and revocations (x-nemo/SessionRevoke or management push) take effect immediately across all gates.

2. Cryptographic Preimages & Canonicalization Semantics (Section 3)

  • Canonicalization: Standardized on RFC 8785 (JSON Canonicalization Scheme - JCS) with UTF-8 encoding.
  • Wire Signing Preimage (sec.enterprise.crypto):
    • Signed object: Complete hook event/response document with the self-referential signature property (extensions["sec.enterprise.crypto"].signature) and canonical_hash excluded prior to canonicalization.
    • Domain separator: Prefixed with strict domain tag agent-hooks/0.1:sec.enterprise.crypto:v1\n.
    • Preimage bytes: PREIMAGE = "agent-hooks/0.1:sec.enterprise.crypto:v1\n" || JCS(payload_without_sig).
    • Freshness & Verification Failure: Enforces ISO-8601 timestamp skew window (±300s) and UUID replay checks. If key_id is unknown/revoked or verification fails, the PEP MUST fail closed (decision: "deny").
  • Audit Ledger Chain (sec.enterprise.audit):
    • Scope: Isolated per session_id.
    • Genesis: Fixed 64 zero hex characters ("0000000000000000000000000000000000000000000000000000000000000000") for sequence: 0.
    • Preimage: record_hash = HASH(prev_record_hash || JCS(record_body)).
    • Anchor: Final record committed to external immutable storage upon session end.
  • TOCTOU Integrity (sec.enterprise.integrity):
    • content_identity = "sha256:" || hex(SHA-256(RFC8785_JCS(tool_input))).
    • If an authorized handler legitimately mutates tool_input, it MUST recompute and return the updated content_identity. Otherwise, dispatch is aborted with deny.

3. HITL Grant & Resumption Security Contract (Section 3.3)

  • Interoperable Token Grant: Supported via either a Signed Grant (JWS/JWT) or an Opaque Grant with Token Introspection.
  • Mandatory Bound Claims: Both formats MUST bind:
    • iss: Authorized HITL authority.
    • aud: Target host/PEP identifier.
    • sub: Original suspended event_id.
    • sid: session_id.
    • tool: tool_name.
    • input_hash: SHA-256(RFC8785_JCS(tool_input)) representing the exact parameters approved by the human.
    • exp: Expiration timestamp.
    • jti: Unique grant ID for atomic single-use tracking.
  • Host Resumption Verification:
    1. Freshness check (now <= exp).
    2. Context check (sub == event_id, sid == session_id, tool == tool_name).
    3. Payload integrity check (recomputed tool input hash == input_hash).
    4. Atomic consume-once check (jti marked consumed; duplicates rejected as replays).

Both npm run validate and npm run build pass cleanly.

@trend-kyle-huang
trend-kyle-huang merged commit 08ecf29 into main Sep 17, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants