unicity-aos/aos-ce · warning
hook-adapter-oracle: dropping principal mismatch for
Error message
hook-adapter-oracle: dropping principal mismatch for {expected.name()} What it means
handle_oracle_hook compares the authenticated caller principal from runtime::caller() against the principal_id embedded in the hook event. If they differ, the event is rejected with this warning and dropped. This prevents a caller from spoofing another principal's identity in hook events — the event's claimed principal must match the actual verified caller.
Solutions
- Set event.principal_id from the actual authenticated caller identity at the point of emission rather than hardcoding it.
- Re-authenticate / refresh the caller identity so the live principal matches the one encoded in the hook payload.
- If a bridge forwards hook events, ensure it preserves or rewrites principal_id to the forwarded caller's verified principal.
- Check the warning context to compare the two principals and correct whichever is stale.
Example fix
// before
let event = OracleHookEvent { principal_id: "user-alice".into(), .. };
dispatch(event); // invoked as user-bob
// after
let event = OracleHookEvent { principal_id: current_verified_principal(), .. };
dispatch(event); Defensive patterns
Strategy: validation
Validate before calling
// Confirm the caller principal before dispatching a hook event let caller = runtime::caller()?; assert_eq!(caller.principal.as_deref(), Some(event.principal_id.as_str()), "principal_id in payload must match verified caller");
Prevention
- Always derive event.principal_id from the verified runtime caller identity, never hardcode it.
- Refresh credentials/identity before long-running processes emit hooks.
- Ensure intermediaries (bridges) forward or rewrite principal_id to the actual caller.
When it happens
Trigger: Raised in handle_oracle_hook when event.principal_id (a string taken from the hook payload) does not equal the verified caller.principal returned by runtime::caller(). Any code path on_codex_hook/on_claude_hook/on_grok_hook invoking the adapter with a payload whose principal_id field was set independently of the actual caller triggers it.
Common situations: A hook producer hardcodes or misconfigures principal_id in the event payload; the hook is invoked through an intermediary/bridge that forwards a stale or different principal; identity rotation or re-auth means the payload's principal_id is outdated relative to the live caller identity.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- hook-adapter-oracle: dropping mismatched context reply on
- hook-bridge: dropping response with mismatched route or…
- canonical document exceeds bound
- Unicity AOS health service must bind to 127.0.0.1
- must not be empty
AI-assisted analysis of unicity-aos/aos-ce@f6f22024fb (2026-09-13).
Data as JSON: /api/errors/132bbe7a40acb621.
Report an issue: GitHub.
Appendix: source
Thrown at capsules/capsule-hook-adapter-oracle/src/lib.rs:383
expected.name()
));
return Ok(());
}
};
let mapping = match validate_oracle_hook(expected, &event) {
Ok(mapping) => mapping,
Err(reason) => {
log::warn(format!(
"hook-adapter-oracle: dropping invalid {} hook '{}': {reason}",
expected.name(),
event.event
));
return Ok(());
}
};
let caller = runtime::caller()?;
if caller.principal.as_deref() != Some(event.principal_id.as_str()) {
log::warn(format!(
"hook-adapter-oracle: dropping principal mismatch for {}",
expected.name()
));
return Ok(());
}
let context = dispatch_oracle_hook(&event, mapping)?;
ipc::publish_json(
&format!("oracle.v1.hook.response.{}", event.delivery_id),
&OracleHookResponse {
schema_version: 1,
principal_id: &event.principal_id,
host: &event.host,
session_id: &event.session_id,
canonical_hook: mapping.hook,
event: &event.event,
correlation_id: &event.correlation_id,
route_id: &event.route_id,View on GitHub (pinned to f6f22024fb)