Skip to content

feat: implement Problem 04 Delegatable Auth with simulation and valid…#85

Open
mahesh-morde wants to merge 3 commits into
projnanda:mainfrom
mahesh-morde:hackathon/mahesh-delegatable-auth
Open

feat: implement Problem 04 Delegatable Auth with simulation and valid…#85
mahesh-morde wants to merge 3 commits into
projnanda:mainfrom
mahesh-morde:hackathon/mahesh-delegatable-auth

Conversation

@mahesh-morde

Copy link
Copy Markdown

feat: implement Problem 04 Delegatable Auth with simulation and valid…

Copilot AI review requested due to automatic review settings July 7, 2026 13:07

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new “delegatable” auth plugin and an accompanying built-in simulation scenario (“delegated_auth”) to exercise capability delegation with scope narrowing and cascading revocation, plus validators and unit tests to enforce the intended security properties.

Changes:

  • Introduces DelegatableAuth (macaroon-style chained delegation + cascading revocation) as a reference auth plugin and registers it in the plugin registry.
  • Adds a built-in delegated_auth scenario + YAML configuration and hooks it into the scenario factory loader.
  • Adds scenario validators and a comprehensive test suite for delegation, revocation, TTL capping, determinism, and audience enforcement.

Reviewed changes

Copilot reviewed 8 out of 10 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
scenarios/delegated_auth.yaml New scenario definition for delegated auth simulation run.
packages/nest-plugins-reference/nest_plugins_reference/auth/delegatable.py New DelegatableAuth implementation (issue/verify/revoke + delegate).
packages/nest-core/tests/test_delegatable_auth.py New unit tests covering delegated auth behavior and attack resistance.
packages/nest-core/nest_core/validators.py Adds delegated-auth validators and registers them under VALIDATORS["delegated_auth"].
packages/nest-core/nest_core/scenarios.py Registers delegated_auth built-in scenario loader branch.
packages/nest-core/nest_core/scenarios_builtin/delegated_auth.py New built-in scenario agent fleet implementing the delegation topology.
packages/nest-core/nest_core/plugins.py Registers the new ("auth", "delegatable") plugin mapping.
.gitignore Adds ignores (currently looks unrelated to this PR’s scope).
git_log.txt New file containing a git log snippet (appears unrelated to this PR).
git_status.txt Empty file included in PR context.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +3807 to +3812
return [ValidationResult(
"delegated_auth_audience_confusion",
False,
"Audience confusion occurred and was rejected"
)]
return [ValidationResult("delegated_auth_audience_confusion", True, "No audience confusion observed")]
Comment on lines +3790 to +3794
return [ValidationResult(
"delegated_auth_stale_parent",
True,
f"Cascading revocation succeeded (observed {failed_verifications} cascading failures)"
)]
Comment on lines +29 to +30
import asyncio
from typing import Any
Comment on lines +296 to +298
root_scopes = ["read", "write", "exec", "admin"]
delegate_scopes = ["read", "write", "exec"]
leaf_scopes = ["read", "exec"]
Comment on lines +11 to +13
revokes one intermediary's token; the downstream 4 leaves must fail
verification. Three adversarial validators check: no scope escalation
occurred, no stale-parent token was accepted, and no audience confusion.
Comment thread git_log.txt Outdated
Comment on lines +1 to +5
commit bb8e67dad32af0b3b4f25636138628fbe8f7a13f
Author: mariagorskikh <maria@maritime.sh>
Date: Mon Jul 6 15:41:26 2026 -0700

Add mobile nav menu to the header
@mahesh-morde mahesh-morde force-pushed the hackathon/mahesh-delegatable-auth branch 2 times, most recently from ed61983 to cebd6fc Compare July 7, 2026 13:24
@dhve

dhve commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Thanks @mahesh-morde. I pulled the branch and ran it, and the core of this is solid: DelegatableAuth in delegatable.py anchors each child's HMAC to its parent's fingerprint, caps child TTL at the parent's remaining lifetime in delegate(), and keeps the base Auth protocol intact by taking presenter as an optional kwarg on verify() instead of a breaking positional change. All 31 tests pass locally, and the hypothesis property test asserting "delegation succeeds if and only if child scopes are a subset of the parent's" is exactly the invariant-level rigor the rubric rewards.

Not ready to merge as-is though. Four things to work through:

1. The validators never fail against the jwt baseline, and one of them cannot fail at all.

The problem statement is explicit: the validator must FAIL against the default jwt plugin and PASS against yours. I ran scenarios/delegated_auth.yaml with auth: jwt and all three validators pass. Because the scenario agents guard everything behind hasattr(auth, "delegate"), the jwt run silently emits only the root auth:issue broadcast: no delegations, no revoke. So validate_delegated_auth_stale_parent passes vacuously ("observed 0 cascading failures") and validate_delegated_auth_no_escalation has nothing to inspect. Worse, validate_delegated_auth_audience_confusion in validators.py returns passed=True on both of its code paths, so it is structurally incapable of failing. Look at how the escrow_marketplace validators handle this: when the plugin lacks the capability, validate_escrow_state_machine fails with "no escrow lifecycle events observed in trace". Do the same here: fail when the trace has zero auth:delegate: events, fail when a revoke happened but no downstream RevokedAncestorError followed, and fail the audience validator when the scenario's deliberate wrong-presenter probe produces no AudienceConfusionError. Then re-run with auth: jwt and confirm all three go red. This is the mandatory adversarial-validator requirement, so it is the highest-priority fix (correctness and test rigor both hang on it).

2. The simulation path is non-deterministic: same seed, different trace bytes.

delegated_auth_factory instantiates the plugin as auth_cls(), so clock=None and _now() falls back to time.time(). Token claims (iat, exp), the tid derived from them in _next_tid, the parent fingerprints, and the signatures all inherit wall-clock time, and those token strings land in the trace via ctx.send. I ran the scenario twice with seed 42 and the traces differ from the first TOKEN: send onward (even the recorded message sizes differ). Tier 1 determinism is non-negotiable per the charter. The fix is small: pass a deterministic clock at instantiation in the factory, for example plugins["auth"] = auth_cls(clock=0.0) (JwtAuth accepts the same kwarg), and keep tick() for the unit tests. Verify with two runs and a byte diff.

3. The branch conflicts with main and lint is red.

A 3-way merge against current main conflicts in nest_core/scenarios.py, nest_core/validators.py, and packages/nest-plugins-reference/pyproject.toml (main has grown since you branched), so please rebase. No CI has run on this branch yet, and locally ruff check reports 28 errors across the three new files (trailing whitespace, unsorted imports, the mid-file from hypothesis import ... in test_delegatable_auth.py triggering E402, long lines), and ruff format --check would reformat all three. The judge panel does not score broken PRs, so get all five make ci-local stages green.

4. Scope hygiene and the PR body.

The .gitignore change adding brain.md and user-steps.md is personal working-notes leakage into shared config (and drops the trailing newline); please remove it. The PR body is currently one truncated line. The docs dimension wants motivation, design, tradeoffs, and a runnable verification snippet, and with roughly twenty open PRs on Problem 04, novelty will be scored against a crowd: state explicitly what differentiates yours (my read: the property-based subset invariant and the protocol-safe optional presenter audience binding) and make that load-bearing in the body.

Suggested path forward:

  1. Rebase onto latest main and resolve the three conflicts.
  2. Rework the three validators to fail on a missing delegation lifecycle; confirm red on auth: jwt, green on delegatable.
  3. Instantiate the plugin with a deterministic clock in the factory; run twice, diff the traces.
  4. Drop the .gitignore change, and consider moving test_delegatable_auth.py to packages/nest-plugins-reference/tests/ where the other plugin suites live.
  5. Run make ci-local until all five stages pass.
  6. Rewrite the PR body: motivation, design, tradeoffs, runnable snippet, and your differentiator.

Leaving this open. Ping me on the hackathon channel if the validator-discrimination pattern is unclear; the escrow_marketplace scenario docstring is the model to copy.

@mahesh-morde mahesh-morde force-pushed the hackathon/mahesh-delegatable-auth branch from d40e62d to 32b528f Compare July 10, 2026 09:28
@mahesh-morde

Copy link
Copy Markdown
Author

Hi @dhve , thanks for the detailed review and guidance! I've just pushed a new commit addressing all four of your points.

  1. Adversarial Validators: I've reworked the 3 validators to explicitly fail if the required delegation lifecycle events, revokes, or audience confusion rejections are missing from the trace. I confirmed that they now go red on the jwt baseline and green on the delegatable trace.
  2. Determinism: In delegated_auth_factory, the plugin is now instantiated with a deterministic clock (plugins["auth"] = auth_cls(clock=0.0)). Tested this out and the trace outputs are now completely deterministic.
  3. Conflicts & Linting: I rebased onto the latest main, resolved the conflicts in the scenarios and validators, fixed the E402 and formatting errors with ruff, and verified that the entire test suite is green locally.
  4. Hygiene & Documentation: I dropped the unintentional .gitignore changes, moved test_delegatable_auth.py into packages/nest-plugins-reference/tests/, and completely rewrote the PR body to include the motivation, design, tradeoffs, runnable snippet, and my specific differentiators.

Let me know if there's anything else needed before we merge!

@mahesh-morde mahesh-morde force-pushed the hackathon/mahesh-delegatable-auth branch from 32b528f to 4feebbb Compare July 13, 2026 07:20
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.

3 participants