use super::admission_clock::ClockSample;
use super::org::OrgId;
use super::org_admission_replay::{AdmissionReplayGuard, ReplayOutcome, ReplayPrincipal};
use super::org_call::{OrgCallProof, MAX_ORG_CALL_PROOF_BYTES};
use super::org_grant::CapabilityAuthorityId;
use super::org_revocation::OrgRevocationState;
use crate::adapter::net::identity::{EntityId, MAX_TOKEN_CLOCK_SKEW_SECS};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum OrgAdmission {
PublicAuthenticated,
OwnerDelegated,
CrossOrgGranted,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AdmissionDenied {
NotOrgProtected,
MissingHeader,
MultipleHeaders,
MalformedProof,
StreamingUnsupported,
MemberBindingMismatch,
ActingOrgMismatch,
UnexpectedCapabilityGrant,
MissingCapabilityGrant,
ForeignIssuer,
GranteeMismatch,
InsufficientRights,
CapabilityMismatch,
TargetNotCovered,
DispatcherGrantScope,
DispatcherGrantInvalid,
MembershipInvalid,
MembershipRevoked,
CapabilityGrantInvalid,
ProofExpired,
BindingInvalid,
ProviderAuthorityUnavailable,
AuthorityChanged,
Replay,
CallIdCollision,
ReplayCapacity,
PerCallerReplayCapacity,
PerOrganizationReplayCapacity,
ExternalPoolReplayCapacity,
ProviderPolicyRejected,
}
impl std::fmt::Display for AdmissionDenied {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "admission denied: {self:?}")
}
}
impl std::error::Error for AdmissionDenied {}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CoarseAdmissionReason {
Denied,
NotSupported,
Unavailable,
}
impl CoarseAdmissionReason {
pub fn to_wire(self) -> u8 {
match self {
Self::Denied => 0,
Self::NotSupported => 1,
Self::Unavailable => 2,
}
}
pub fn from_wire(v: u8) -> Option<Self> {
match v {
0 => Some(Self::Denied),
1 => Some(Self::NotSupported),
2 => Some(Self::Unavailable),
_ => None,
}
}
}
impl AdmissionDenied {
pub fn coarse(self) -> CoarseAdmissionReason {
use AdmissionDenied as D;
use CoarseAdmissionReason as C;
match self {
D::ProviderAuthorityUnavailable
| D::AuthorityChanged
| D::ReplayCapacity
| D::PerCallerReplayCapacity
| D::PerOrganizationReplayCapacity
| D::ExternalPoolReplayCapacity => C::Unavailable,
D::StreamingUnsupported => C::NotSupported,
D::NotOrgProtected
| D::MissingHeader
| D::MultipleHeaders
| D::MalformedProof
| D::MemberBindingMismatch
| D::ActingOrgMismatch
| D::UnexpectedCapabilityGrant
| D::MissingCapabilityGrant
| D::ForeignIssuer
| D::GranteeMismatch
| D::InsufficientRights
| D::CapabilityMismatch
| D::TargetNotCovered
| D::DispatcherGrantScope
| D::DispatcherGrantInvalid
| D::MembershipInvalid
| D::MembershipRevoked
| D::CapabilityGrantInvalid
| D::ProofExpired
| D::BindingInvalid
| D::Replay
| D::CallIdCollision
| D::ProviderPolicyRejected => C::Denied,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Admitted {
pub caller: EntityId,
pub acting_org: OrgId,
pub provider_org: OrgId,
pub provider: EntityId,
pub capability: CapabilityAuthorityId,
}
pub struct AdmissionContext<'a> {
pub mode: OrgAdmission,
pub authenticated_caller: &'a EntityId,
pub provider: &'a EntityId,
pub provider_owner_org: OrgId,
pub invoked_capability: CapabilityAuthorityId,
pub call_id: u64,
pub request_digest: [u8; 32],
pub is_unary: bool,
pub floors: &'a OrgRevocationState,
pub skew_secs: u64,
}
pub fn verify_org_admission(
ctx: &AdmissionContext,
admission_headers: &[&[u8]],
replay: &AdmissionReplayGuard,
clock: ClockSample,
stability_recheck: impl FnOnce() -> bool,
provider_policy: impl FnOnce(&OrgCallProof) -> bool,
) -> Result<Admitted, AdmissionDenied> {
match ctx.mode {
OrgAdmission::OwnerDelegated | OrgAdmission::CrossOrgGranted => {}
OrgAdmission::PublicAuthenticated => return Err(AdmissionDenied::NotOrgProtected),
}
let header = match admission_headers {
[] => return Err(AdmissionDenied::MissingHeader),
[one] => *one,
_ => return Err(AdmissionDenied::MultipleHeaders),
};
if header.len() > MAX_ORG_CALL_PROOF_BYTES {
return Err(AdmissionDenied::MalformedProof);
}
let proof = OrgCallProof::decode(header).map_err(|_| AdmissionDenied::MalformedProof)?;
if !ctx.is_unary {
return Err(AdmissionDenied::StreamingUnsupported);
}
if &proof.caller_membership.member != ctx.authenticated_caller {
return Err(AdmissionDenied::MemberBindingMismatch);
}
let acting_org = proof.caller_membership.org_id;
if proof.dispatcher_grant.org_id != acting_org {
return Err(AdmissionDenied::ActingOrgMismatch);
}
match ctx.mode {
OrgAdmission::OwnerDelegated => {
if acting_org != ctx.provider_owner_org {
return Err(AdmissionDenied::GranteeMismatch);
}
if proof.capability_grant.is_some() {
return Err(AdmissionDenied::UnexpectedCapabilityGrant);
}
}
OrgAdmission::CrossOrgGranted => {
let grant = proof
.capability_grant
.as_ref()
.ok_or(AdmissionDenied::MissingCapabilityGrant)?;
if grant.issuer_org != ctx.provider_owner_org {
return Err(AdmissionDenied::ForeignIssuer);
}
if grant.grantee_org != acting_org {
return Err(AdmissionDenied::GranteeMismatch);
}
if !grant.permits_invoke() {
return Err(AdmissionDenied::InsufficientRights);
}
if grant.capability != ctx.invoked_capability {
return Err(AdmissionDenied::CapabilityMismatch);
}
if !grant
.target_scope
.covers(ctx.provider, Some(&ctx.provider_owner_org))
{
return Err(AdmissionDenied::TargetNotCovered);
}
}
OrgAdmission::PublicAuthenticated => unreachable!("filtered in step 1"),
}
if proof.dispatcher_grant.dispatcher != *ctx.authenticated_caller
|| !proof
.dispatcher_grant
.covers_capability(&ctx.invoked_capability)
{
return Err(AdmissionDenied::DispatcherGrantScope);
}
let now_secs = clock.wall_secs();
proof
.caller_membership
.is_valid_at_with_skew(now_secs, ctx.skew_secs)
.map_err(|_| AdmissionDenied::MembershipInvalid)?;
let floor = ctx
.floors
.floor_for(&acting_org, &proof.caller_membership.member);
if proof.caller_membership.generation < floor {
return Err(AdmissionDenied::MembershipRevoked);
}
proof
.dispatcher_grant
.is_valid_at_with_skew(now_secs, ctx.skew_secs)
.map_err(|_| AdmissionDenied::DispatcherGrantInvalid)?;
if let Some(grant) = &proof.capability_grant {
grant
.is_valid_at_with_skew(now_secs, ctx.skew_secs)
.map_err(|_| AdmissionDenied::CapabilityGrantInvalid)?;
}
proof
.check_expiry_at(clock.wall_ns, ctx.skew_secs)
.map_err(|_| AdmissionDenied::ProofExpired)?;
let binding = proof.binding_for_verify(
ctx.provider_owner_org,
ctx.provider.clone(),
ctx.call_id,
ctx.invoked_capability,
ctx.request_digest,
);
binding
.verify(&proof.call_binding_sig)
.map_err(|_| AdmissionDenied::BindingInvalid)?;
if !stability_recheck() {
return Err(AdmissionDenied::AuthorityChanged);
}
let binding_digest: [u8; 32] = blake3::hash(&proof.call_binding_sig).into();
let skew_ns = MAX_TOKEN_CLOCK_SKEW_SECS.saturating_mul(1_000_000_000);
let retain_until_wall_ns = proof.proof_expires_at_unix_ns.saturating_add(skew_ns);
let expires_at = clock.monotonic_deadline_for(retain_until_wall_ns);
let principal = ReplayPrincipal {
caller: ctx.authenticated_caller,
acting_org: &acting_org,
provider_owner_org: &ctx.provider_owner_org,
};
match replay.admit(
principal,
ctx.call_id,
binding_digest,
expires_at,
clock.monotonic,
) {
ReplayOutcome::Admitted => {}
ReplayOutcome::Replay => return Err(AdmissionDenied::Replay),
ReplayOutcome::CallIdCollision => return Err(AdmissionDenied::CallIdCollision),
ReplayOutcome::CapacityExhausted => return Err(AdmissionDenied::ReplayCapacity),
ReplayOutcome::PerCallerCapacityExhausted => {
return Err(AdmissionDenied::PerCallerReplayCapacity)
}
ReplayOutcome::PerOrganizationCapacityExhausted => {
return Err(AdmissionDenied::PerOrganizationReplayCapacity)
}
ReplayOutcome::ExternalPoolCapacityExhausted => {
return Err(AdmissionDenied::ExternalPoolReplayCapacity)
}
}
if !provider_policy(&proof) {
return Err(AdmissionDenied::ProviderPolicyRejected);
}
Ok(Admitted {
caller: proof.caller_membership.member.clone(),
acting_org,
provider_org: ctx.provider_owner_org,
provider: ctx.provider.clone(),
capability: ctx.invoked_capability,
})
}
#[cfg(test)]
mod tests {
use super::*;
use crate::adapter::net::behavior::org::{OrgKeypair, OrgMembershipCert, OrgRevocationBundle};
use crate::adapter::net::behavior::org_grant::{
DispatcherScope, GrantRights, GrantTargetScope, OrgCapabilityGrant, OrgDispatcherGrant,
};
use crate::adapter::net::identity::EntityKeypair;
use std::collections::BTreeMap;
use std::time::Duration;
fn org_b() -> OrgKeypair {
OrgKeypair::from_bytes([0x42u8; 32])
}
fn org_a() -> OrgKeypair {
OrgKeypair::from_bytes([0x77u8; 32])
}
fn caller() -> EntityKeypair {
EntityKeypair::from_bytes([0x24u8; 32])
}
fn provider() -> EntityId {
EntityId::from_bytes([0x99u8; 32])
}
fn cap() -> CapabilityAuthorityId {
CapabilityAuthorityId::for_tag("nrpc:oa2-echo")
}
fn empty_floors() -> OrgRevocationState {
OrgRevocationState::empty()
}
const REQ: [u8; 32] = [0x11u8; 32];
const CALL_ID: u64 = 42;
fn cross_org_proof() -> OrgCallProof {
cross_org_proof_for_call(CALL_ID)
}
fn cross_org_proof_for_call(call_id: u64) -> OrgCallProof {
let caller = caller();
let membership =
OrgMembershipCert::try_issue(&org_a(), caller.entity_id().clone(), 1, 3600)
.expect("cert");
let dispatcher = OrgDispatcherGrant::try_issue(
&org_a(),
caller.entity_id().clone(),
DispatcherScope::Exact(cap()),
3600,
)
.expect("dispatcher");
let (grant, _) = OrgCapabilityGrant::try_issue(
&org_b(),
org_a().org_id(),
cap(),
GrantRights::INVOKE,
GrantTargetScope::ExactNode(provider()),
3600,
)
.expect("grant");
let expiry = (crate::adapter::net::behavior::org::current_timestamp() + 20) * 1_000_000_000;
OrgCallProof::sign_for_call(
&caller,
membership,
dispatcher,
Some(grant),
org_a().org_id(),
org_b().org_id(),
provider(),
call_id,
cap(),
expiry,
REQ,
)
}
fn owner_delegated_proof() -> OrgCallProof {
let caller = caller();
let membership =
OrgMembershipCert::try_issue(&org_b(), caller.entity_id().clone(), 1, 3600)
.expect("cert");
let dispatcher = OrgDispatcherGrant::try_issue(
&org_b(),
caller.entity_id().clone(),
DispatcherScope::Exact(cap()),
3600,
)
.expect("dispatcher");
let expiry = (crate::adapter::net::behavior::org::current_timestamp() + 20) * 1_000_000_000;
OrgCallProof::sign_for_call(
&caller,
membership,
dispatcher,
None,
org_b().org_id(),
org_b().org_id(),
provider(),
CALL_ID,
cap(),
expiry,
REQ,
)
}
fn cross_org_ctx(floors: &OrgRevocationState) -> AdmissionContext<'_> {
AdmissionContext {
mode: OrgAdmission::CrossOrgGranted,
authenticated_caller: Box::leak(Box::new(caller().entity_id().clone())),
provider: Box::leak(Box::new(provider())),
provider_owner_org: org_b().org_id(),
invoked_capability: cap(),
call_id: CALL_ID,
request_digest: REQ,
is_unary: true,
floors,
skew_secs: 0,
}
}
fn owner_ctx(floors: &OrgRevocationState) -> AdmissionContext<'_> {
AdmissionContext {
mode: OrgAdmission::OwnerDelegated,
authenticated_caller: Box::leak(Box::new(caller().entity_id().clone())),
provider: Box::leak(Box::new(provider())),
provider_owner_org: org_b().org_id(),
invoked_capability: cap(),
call_id: CALL_ID,
request_digest: REQ,
is_unary: true,
floors,
skew_secs: 0,
}
}
fn admit(
ctx: &AdmissionContext,
proof: &OrgCallProof,
replay: &AdmissionReplayGuard,
) -> Result<Admitted, AdmissionDenied> {
let bytes = proof.encode().expect("encode");
verify_org_admission(
ctx,
&[&bytes],
replay,
ClockSample::now(),
|| true,
|_| true,
)
}
#[test]
fn cross_org_happy_path_admits_with_four_party_attribution() {
let floors = empty_floors();
let ctx = cross_org_ctx(&floors);
let replay = AdmissionReplayGuard::with_defaults();
let admitted = admit(&ctx, &cross_org_proof(), &replay).expect("admit");
assert_eq!(admitted.caller, *caller().entity_id());
assert_eq!(admitted.acting_org, org_a().org_id());
assert_eq!(admitted.provider_org, org_b().org_id());
assert_eq!(admitted.provider, provider());
assert_eq!(admitted.capability, cap());
}
#[test]
fn owner_delegated_happy_path_admits() {
let floors = empty_floors();
let ctx = owner_ctx(&floors);
let replay = AdmissionReplayGuard::with_defaults();
let admitted = admit(&ctx, &owner_delegated_proof(), &replay).expect("admit");
assert_eq!(admitted.acting_org, org_b().org_id());
assert!(admitted.provider_org == admitted.acting_org, "same-org");
}
#[test]
fn public_mode_is_not_handled_here() {
let floors = empty_floors();
let mut ctx = cross_org_ctx(&floors);
ctx.mode = OrgAdmission::PublicAuthenticated;
let replay = AdmissionReplayGuard::with_defaults();
assert_eq!(
admit(&ctx, &cross_org_proof(), &replay),
Err(AdmissionDenied::NotOrgProtected)
);
}
#[test]
fn header_discipline_exactly_one() {
let floors = empty_floors();
let ctx = cross_org_ctx(&floors);
let replay = AdmissionReplayGuard::with_defaults();
let bytes = cross_org_proof().encode().expect("encode");
assert_eq!(
verify_org_admission(&ctx, &[], &replay, ClockSample::now(), || true, |_| true),
Err(AdmissionDenied::MissingHeader)
);
assert_eq!(
verify_org_admission(
&ctx,
&[&bytes, &bytes],
&replay,
ClockSample::now(),
|| true,
|_| true
),
Err(AdmissionDenied::MultipleHeaders)
);
}
#[test]
fn malformed_and_streaming_are_distinct() {
let floors = empty_floors();
let ctx = cross_org_ctx(&floors);
let replay = AdmissionReplayGuard::with_defaults();
assert_eq!(
verify_org_admission(
&ctx,
&[b"garbage"],
&replay,
ClockSample::now(),
|| true,
|_| true
),
Err(AdmissionDenied::MalformedProof)
);
let mut streaming = cross_org_ctx(&floors);
streaming.is_unary = false;
assert_eq!(
admit(&streaming, &cross_org_proof(), &replay),
Err(AdmissionDenied::StreamingUnsupported)
);
}
#[test]
fn tofu_member_binding_rejects_a_relayed_proof() {
let floors = empty_floors();
let mut ctx = cross_org_ctx(&floors);
let other = EntityId::from_bytes([0xEEu8; 32]);
ctx.authenticated_caller = &other;
let replay = AdmissionReplayGuard::with_defaults();
assert_eq!(
admit(&ctx, &cross_org_proof(), &replay),
Err(AdmissionDenied::MemberBindingMismatch)
);
}
#[test]
fn owner_delegated_rejects_an_unexpected_capability_grant() {
let caller = caller();
let membership =
OrgMembershipCert::try_issue(&org_b(), caller.entity_id().clone(), 1, 3600)
.expect("cert");
let dispatcher = OrgDispatcherGrant::try_issue(
&org_b(),
caller.entity_id().clone(),
DispatcherScope::Exact(cap()),
3600,
)
.expect("dispatcher");
let (grant, _) = OrgCapabilityGrant::try_issue(
&org_b(),
org_b().org_id(),
cap(),
GrantRights::INVOKE,
GrantTargetScope::ExactNode(provider()),
3600,
)
.expect("grant");
let expiry = (crate::adapter::net::behavior::org::current_timestamp() + 20) * 1_000_000_000;
let proof = OrgCallProof::sign_for_call(
&caller,
membership,
dispatcher,
Some(grant),
org_b().org_id(),
org_b().org_id(),
provider(),
CALL_ID,
cap(),
expiry,
REQ,
);
let floors = empty_floors();
let ctx = owner_ctx(&floors);
let replay = AdmissionReplayGuard::with_defaults();
assert_eq!(
admit(&ctx, &proof, &replay),
Err(AdmissionDenied::UnexpectedCapabilityGrant)
);
}
#[test]
fn cross_org_mode_check_matrix() {
let floors = empty_floors();
let replay = AdmissionReplayGuard::with_defaults();
let owner_proof = owner_delegated_proof();
assert_eq!(
admit(&cross_org_ctx(&floors), &owner_proof, &replay),
Err(AdmissionDenied::MissingCapabilityGrant)
);
let caller = caller();
let membership =
OrgMembershipCert::try_issue(&org_a(), caller.entity_id().clone(), 1, 3600)
.expect("cert");
let dispatcher = OrgDispatcherGrant::try_issue(
&org_a(),
caller.entity_id().clone(),
DispatcherScope::Exact(cap()),
3600,
)
.expect("dispatcher");
let (foreign_grant, _) = OrgCapabilityGrant::try_issue(
&org_a(), org_a().org_id(),
cap(),
GrantRights::INVOKE,
GrantTargetScope::ExactNode(provider()),
3600,
)
.expect("grant");
let expiry = (crate::adapter::net::behavior::org::current_timestamp() + 20) * 1_000_000_000;
let foreign = OrgCallProof::sign_for_call(
&caller,
membership.clone(),
dispatcher.clone(),
Some(foreign_grant),
org_a().org_id(),
org_b().org_id(),
provider(),
CALL_ID,
cap(),
expiry,
REQ,
);
assert_eq!(
admit(&cross_org_ctx(&floors), &foreign, &replay),
Err(AdmissionDenied::ForeignIssuer)
);
let (wrong_target, _) = OrgCapabilityGrant::try_issue(
&org_b(),
org_a().org_id(),
cap(),
GrantRights::INVOKE,
GrantTargetScope::ExactNode(EntityId::from_bytes([0x55u8; 32])),
3600,
)
.expect("grant");
let mistargeted = OrgCallProof::sign_for_call(
&caller,
membership.clone(),
dispatcher.clone(),
Some(wrong_target),
org_a().org_id(),
org_b().org_id(),
provider(),
CALL_ID,
cap(),
expiry,
REQ,
);
assert_eq!(
admit(&cross_org_ctx(&floors), &mistargeted, &replay),
Err(AdmissionDenied::TargetNotCovered)
);
let (discover_only, _) = OrgCapabilityGrant::try_issue(
&org_b(),
org_a().org_id(),
cap(),
GrantRights::DISCOVER,
GrantTargetScope::ExactNode(provider()),
3600,
)
.expect("grant");
let no_invoke = OrgCallProof::sign_for_call(
&caller,
membership,
dispatcher,
Some(discover_only),
org_a().org_id(),
org_b().org_id(),
provider(),
CALL_ID,
cap(),
expiry,
REQ,
);
assert_eq!(
admit(&cross_org_ctx(&floors), &no_invoke, &replay),
Err(AdmissionDenied::InsufficientRights)
);
}
#[test]
fn capability_mismatch_when_invoked_tag_differs() {
let floors = empty_floors();
let mut ctx = cross_org_ctx(&floors);
ctx.invoked_capability = CapabilityAuthorityId::for_tag("nrpc:other");
let replay = AdmissionReplayGuard::with_defaults();
assert_eq!(
admit(&ctx, &cross_org_proof(), &replay),
Err(AdmissionDenied::CapabilityMismatch)
);
}
#[test]
fn revocation_floor_kills_the_membership() {
let mut floors = OrgRevocationState::empty();
let mut map = BTreeMap::new();
map.insert(caller().entity_id().clone(), 2u32);
floors.merge_bundle(&OrgRevocationBundle::try_issue(&org_a(), &map).expect("bundle"));
let ctx = cross_org_ctx(&floors);
let replay = AdmissionReplayGuard::with_defaults();
assert_eq!(
admit(&ctx, &cross_org_proof(), &replay),
Err(AdmissionDenied::MembershipRevoked)
);
}
#[test]
fn binding_rejects_a_transplanted_call() {
let floors = empty_floors();
let replay = AdmissionReplayGuard::with_defaults();
let mut ctx = cross_org_ctx(&floors);
ctx.call_id = CALL_ID + 1;
assert_eq!(
admit(&ctx, &cross_org_proof(), &replay),
Err(AdmissionDenied::BindingInvalid)
);
let mut ctx = cross_org_ctx(&floors);
ctx.request_digest = [0x22u8; 32];
assert_eq!(
admit(&ctx, &cross_org_proof(), &replay),
Err(AdmissionDenied::BindingInvalid)
);
}
#[test]
fn replay_then_collision_are_distinguished() {
let floors = empty_floors();
let ctx = cross_org_ctx(&floors);
let replay = AdmissionReplayGuard::with_defaults();
let proof = cross_org_proof();
admit(&ctx, &proof, &replay).expect("first admit");
assert_eq!(admit(&ctx, &proof, &replay), Err(AdmissionDenied::Replay));
let other = cross_org_proof();
assert_eq!(
admit(&ctx, &other, &replay),
Err(AdmissionDenied::CallIdCollision)
);
}
#[test]
fn provider_policy_runs_last_and_can_veto() {
let floors = empty_floors();
let ctx = cross_org_ctx(&floors);
let replay = AdmissionReplayGuard::with_defaults();
let bytes = cross_org_proof().encode().expect("encode");
let out = verify_org_admission(
&ctx,
&[&bytes],
&replay,
ClockSample::now(),
|| true,
|_| false,
);
assert_eq!(out, Err(AdmissionDenied::ProviderPolicyRejected));
}
#[test]
fn admission_uses_one_clock_sample_for_freshness_and_retention() {
let floors = empty_floors();
let ctx = cross_org_ctx(&floors);
let proof = cross_org_proof();
let bytes = proof.encode().expect("encode");
let expiry_ns = proof.proof_expires_at_unix_ns;
let base = ClockSample::now().monotonic;
let stale_guard = AdmissionReplayGuard::with_defaults();
let stale = ClockSample {
wall_ns: expiry_ns + 1_000_000_000,
monotonic: base,
};
assert_eq!(
verify_org_admission(&ctx, &[&bytes], &stale_guard, stale, || true, |_| true),
Err(AdmissionDenied::ProofExpired),
);
assert_eq!(stale_guard.len(), 0, "an expired proof consumes no slot");
let replay = AdmissionReplayGuard::with_defaults();
let fresh = ClockSample {
wall_ns: expiry_ns - 10_000_000_000,
monotonic: base,
};
assert!(verify_org_admission(&ctx, &[&bytes], &replay, fresh, || true, |_| true).is_ok());
let horizon = Duration::from_secs(10 + MAX_TOKEN_CLOCK_SKEW_SECS);
let inside = ClockSample {
wall_ns: expiry_ns - 10_000_000_000,
monotonic: base + Duration::from_secs(5),
};
assert_eq!(
verify_org_admission(&ctx, &[&bytes], &replay, inside, || true, |_| true),
Err(AdmissionDenied::Replay),
);
let old_horizon = ClockSample {
wall_ns: expiry_ns - 10_000_000_000,
monotonic: base + Duration::from_secs(11),
};
assert_eq!(
verify_org_admission(&ctx, &[&bytes], &replay, old_horizon, || true, |_| true),
Err(AdmissionDenied::Replay),
"retention must outlast expiry + ctx.skew_secs (§5)",
);
let past = ClockSample {
wall_ns: expiry_ns - 10_000_000_000,
monotonic: base + horizon + Duration::from_secs(1),
};
assert!(verify_org_admission(&ctx, &[&bytes], &replay, past, || true, |_| true).is_ok());
}
#[test]
fn widening_skew_does_not_reopen_an_already_used_proof() {
let floors = empty_floors();
let proof = cross_org_proof();
let bytes = proof.encode().expect("encode");
let expiry_ns = proof.proof_expires_at_unix_ns;
let base = ClockSample::now().monotonic;
let replay = AdmissionReplayGuard::with_defaults();
let narrow = cross_org_ctx(&floors);
assert_eq!(
narrow.skew_secs, 0,
"fixture must start at the serde default"
);
let admit_at = ClockSample {
wall_ns: expiry_ns - 10_000_000_000,
monotonic: base,
};
assert!(
verify_org_admission(&narrow, &[&bytes], &replay, admit_at, || true, |_| true).is_ok(),
"first use admits",
);
let mut wide = cross_org_ctx(&floors);
wide.skew_secs = MAX_TOKEN_CLOCK_SKEW_SECS;
let resend = ClockSample {
wall_ns: expiry_ns + 200_000_000_000,
monotonic: base + Duration::from_secs(210),
};
assert_eq!(
verify_org_admission(&wide, &[&bytes], &replay, resend, || true, |_| true),
Err(AdmissionDenied::Replay),
"a used proof must stay denied across a runtime skew widening",
);
let mut other = cross_org_ctx(&floors);
other.skew_secs = MAX_TOKEN_CLOCK_SKEW_SECS;
other.call_id = CALL_ID ^ 0xFFFF;
let fresh_proof = cross_org_proof_for_call(other.call_id);
let fresh_bytes = fresh_proof.encode().expect("encode");
assert!(
verify_org_admission(&other, &[&fresh_bytes], &replay, resend, || true, |_| true)
.is_ok(),
"an unused proof at the same instant admits — so §5's denial is \
the replay guard, not expiry",
);
}
#[test]
fn stability_recheck_denies_without_consuming_a_replay_slot() {
let floors = empty_floors();
let ctx = cross_org_ctx(&floors);
let replay = AdmissionReplayGuard::with_defaults();
let bytes = cross_org_proof().encode().expect("encode");
let out = verify_org_admission(
&ctx,
&[&bytes],
&replay,
ClockSample::now(),
|| false,
|_| true,
);
assert_eq!(out, Err(AdmissionDenied::AuthorityChanged));
assert_eq!(replay.len(), 0, "the stale attempt consumed no replay slot");
let out = verify_org_admission(
&ctx,
&[&bytes],
&replay,
ClockSample::now(),
|| true,
|_| true,
);
assert!(out.is_ok(), "retry under a stable view admits");
assert_eq!(replay.len(), 1);
}
#[test]
fn stability_recheck_runs_after_credential_checks() {
let floors = empty_floors();
let mut ctx = cross_org_ctx(&floors);
ctx.is_unary = false;
let replay = AdmissionReplayGuard::with_defaults();
let bytes = cross_org_proof().encode().expect("encode");
let out = verify_org_admission(
&ctx,
&[&bytes],
&replay,
ClockSample::now(),
|| false,
|_| true,
);
assert_eq!(out, Err(AdmissionDenied::StreamingUnsupported));
}
#[test]
fn expired_proof_is_refused() {
let caller = caller();
let membership =
OrgMembershipCert::try_issue(&org_a(), caller.entity_id().clone(), 1, 3600)
.expect("cert");
let dispatcher = OrgDispatcherGrant::try_issue(
&org_a(),
caller.entity_id().clone(),
DispatcherScope::Exact(cap()),
3600,
)
.expect("dispatcher");
let (grant, _) = OrgCapabilityGrant::try_issue(
&org_b(),
org_a().org_id(),
cap(),
GrantRights::INVOKE,
GrantTargetScope::ExactNode(provider()),
3600,
)
.expect("grant");
let past = (crate::adapter::net::behavior::org::current_timestamp().saturating_sub(10))
* 1_000_000_000;
let proof = OrgCallProof::sign_for_call(
&caller,
membership,
dispatcher,
Some(grant),
org_a().org_id(),
org_b().org_id(),
provider(),
CALL_ID,
cap(),
past,
REQ,
);
let floors = empty_floors();
let ctx = cross_org_ctx(&floors);
let replay = AdmissionReplayGuard::with_defaults();
assert_eq!(
admit(&ctx, &proof, &replay),
Err(AdmissionDenied::ProofExpired)
);
}
#[test]
fn every_denial_maps_to_a_defined_coarse_reason() {
const ALL: &[AdmissionDenied] = &[
AdmissionDenied::NotOrgProtected,
AdmissionDenied::MissingHeader,
AdmissionDenied::MultipleHeaders,
AdmissionDenied::MalformedProof,
AdmissionDenied::StreamingUnsupported,
AdmissionDenied::MemberBindingMismatch,
AdmissionDenied::ActingOrgMismatch,
AdmissionDenied::UnexpectedCapabilityGrant,
AdmissionDenied::MissingCapabilityGrant,
AdmissionDenied::ForeignIssuer,
AdmissionDenied::GranteeMismatch,
AdmissionDenied::InsufficientRights,
AdmissionDenied::CapabilityMismatch,
AdmissionDenied::TargetNotCovered,
AdmissionDenied::DispatcherGrantScope,
AdmissionDenied::DispatcherGrantInvalid,
AdmissionDenied::MembershipInvalid,
AdmissionDenied::MembershipRevoked,
AdmissionDenied::CapabilityGrantInvalid,
AdmissionDenied::ProofExpired,
AdmissionDenied::BindingInvalid,
AdmissionDenied::ProviderAuthorityUnavailable,
AdmissionDenied::AuthorityChanged,
AdmissionDenied::Replay,
AdmissionDenied::CallIdCollision,
AdmissionDenied::ReplayCapacity,
AdmissionDenied::PerCallerReplayCapacity,
AdmissionDenied::ProviderPolicyRejected,
];
for &d in ALL {
let c = d.coarse();
assert_eq!(
CoarseAdmissionReason::from_wire(c.to_wire()),
Some(c),
"coarse reason for {d:?} must round-trip through its wire byte",
);
}
assert_eq!(
AdmissionDenied::StreamingUnsupported.coarse(),
CoarseAdmissionReason::NotSupported,
);
for unavailable in [
AdmissionDenied::ProviderAuthorityUnavailable,
AdmissionDenied::AuthorityChanged,
AdmissionDenied::ReplayCapacity,
AdmissionDenied::PerCallerReplayCapacity,
] {
assert_eq!(unavailable.coarse(), CoarseAdmissionReason::Unavailable);
}
for denied in [
AdmissionDenied::BindingInvalid,
AdmissionDenied::Replay,
AdmissionDenied::ProviderPolicyRejected,
AdmissionDenied::MembershipRevoked,
] {
assert_eq!(denied.coarse(), CoarseAdmissionReason::Denied);
}
assert_eq!(CoarseAdmissionReason::from_wire(3), None);
}
}