Skip to content

Bump ic-agent/ic-transport-types to 0.48.0 and forward read-only delegation permissions - #33

Merged
aterga merged 4 commits into
mainfrom
claude/bump-ic-agent-transport-types-f50qx6
Jul 5, 2026
Merged

aterga merged 4 commits into
mainfrom
claude/bump-ic-agent-transport-types-f50qx6

Conversation

@aterga

@aterga aterga commented Jul 5, 2026 •

Copy link
Copy Markdown
Collaborator

What

  • Bumps ic-agent 0.47 → 0.48 (and ic-agent / ic-transport-types to 0.48.0 in Cargo.lock).
  • Decodes Internet Identity's per-MCP-session delegation permission and forwards it into the ic-agent Delegation, so read-only (queries) delegations are honored.
  • Adds an end-to-end test for read-only delegations and wires cargo test into CI.

Why

ic-agent / ic-transport-types 0.48.0 add a permissions field to Delegation and a DelegationPermissions enum (Queries | All) describing which request kinds a signed delegation authorizes — matching II's per-MCP-session read-only delegations (internet-identity#4086). The permissions field is part of what II signs, so it must be forwarded verbatim or the reconstructed delegation won't verify.

Changes

  • Cargo.toml: ic-agent = "0.47" → "0.48".
  • Cargo.lock: ic-agent and ic-transport-types resolved to 0.48.0.
  • src/identities.rs:
    • Decode II's permissions: opt variant { queries; all } from mcp_get_delegation into a local Candid mirror (IiPermissions) — needed because ic-agent's DelegationPermissions isn't CandidType — and map it 1:1 into DelegationPermissions when building the ic-agent Delegation. An absent permission stays None, which hashes identically to a pre-0.48 delegation, so unrestricted sessions are unchanged.
    • signed_delegation_forwards_ii_permissions: locks in the queries/all/absent decode-and-map contract.
    • read_only_delegation_scopes_signed_requests_end_to_end: hermetic e2e over the real decode → DelegatedIdentity → Identity::sign path with an anchor-signed chain. Asserts the read-only scope survives decoding, that an update and a read request both carry the Queries permission (so the replica scopes them to queries/read_state), and that stripping the scope invalidates the delegation signature (a client can't silently widen it to full access).
  • .github/workflows/ci.yml: new workflow running cargo build/cargo test --locked on pull requests and pushes to main. Previously CI only ran the status-dashboard's npm tests, so no Rust tests ran in CI; --locked also guards the dependency pins from silent drift.

ic-transport-types remains a transitive dependency (the code uses the re-exports via ic_agent::identity::…), so it is not added to Cargo.toml.

Testing

  • cargo test — all 37 tests pass.
  • CI test job is green on this PR.

🤖 Generated with Claude Code

https://claude.ai/code/session_01RzjuJVat2CTiCYzeU9F6e2

These versions add the `permissions` field to `Delegation` (with the new
`DelegationPermissions` enum) for read-only delegation support. `Delegation`
is not `#[non_exhaustive]`, so the struct literal built from II's
`mcp_get_delegation` response now sets `permissions: None` explicitly — II
issues full-access delegations for the MCP flow and does not sign a
`permissions` field, and `None` hashes/verifies identically to a pre-0.48
delegation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RzjuJVat2CTiCYzeU9F6e2
Comment thread src/identities.rs Resolved

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

Updates the project’s Internet Computer agent dependency to ic-agent 0.48.x and adjusts the local delegation conversion code to accommodate the newly added permissions field on Delegation while keeping existing MCP delegation behavior unchanged.

Changes:

  • Bumped ic-agent dependency from 0.47 to 0.48 in Cargo.toml.
  • Updated Cargo.lock to resolve ic-agent and ic-transport-types to 0.48.0.
  • Updated IiSignedDelegation::into_agent to set Delegation { permissions: None, ... } for compatibility with the new struct field.

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated no comments.

File Description
src/identities.rs Sets permissions: None when converting II’s mcp_get_delegation response into ic-agent’s Delegation to match the new 0.48 struct shape without changing behavior.
Cargo.toml Bumps ic-agent dependency requirement to 0.48.
Cargo.lock Locks ic-agent and ic-transport-types to 0.48.0 with updated checksums.

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

II carries a per-MCP-session permission (`opt Permissions`,
`variant { queries; all }`) on the delegation returned by
`mcp_get_delegation`, and that field is part of what II signs. Decode it
via a local Candid mirror enum and forward it into the `ic-agent`
`Delegation` (0.48's new `permissions` field) so the reconstructed
delegation hashes to exactly what II signed, instead of hardcoding
`None` and dropping it.

An absent permission still maps to `None`, which hashes identically to a
pre-0.48 delegation, so unrestricted sessions are unaffected. Adds a test
locking in the queries/all decode-and-map and the absent -> None case.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RzjuJVat2CTiCYzeU9F6e2
Comment thread src/identities.rs Resolved
Adds an end-to-end test that drives the full server path for a read-only
(`queries`) delegation — II reply -> `Decode!` -> `IiSignedDelegation::into_agent`
-> `build_identity` -> `Identity::sign` — with a genuinely anchor-signed chain
(no network). It asserts that:

- the read-only scope survives decoding into the `ic-agent` delegation,
- every request the resulting identity signs (an update AND a read) carries the
  `Queries` permission, so the replica scopes both to queries/read_state, and
- the scope is bound into the delegation signature: stripping it to an
  unrestricted delegation changes the signed bytes and invalidates the chain,
  so a client cannot silently widen a read-only delegation to full access.

The shared II wire types (`WirePermissions` / `WireDelegation` /
`WireSignedDelegation`) are lifted to the test module so both permission tests
reuse them.

Also adds a CI workflow that runs `cargo build`/`cargo test --locked` on pull
requests and pushes to main — previously CI only ran the status-dashboard's npm
tests, so no Rust tests (including this one) ran in CI.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RzjuJVat2CTiCYzeU9F6e2
@aterga aterga changed the title Bump ic-agent and ic-transport-types to 0.48.0 Bump ic-agent/ic-transport-types to 0.48.0 and forward read-only delegation permissions Jul 5, 2026
@aterga
aterga marked this pull request as ready for review July 5, 2026 12:06
Copilot AI review requested due to automatic review settings July 5, 2026 12:06

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

Copilot reviewed 3 out of 4 changed files in this pull request and generated 1 comment.

Comment thread src/identities.rs Resolved
The existing "absent permission" case encoded `permissions: None`, which
Candid still serializes as an `opt`-null field. A genuine pre-0.48 II
reply omits the `permissions` field from the `Delegation` record
entirely, which is a distinct wire type. Add a field-less legacy fixture
and assert it decodes to `None`, locking in backward compatibility with
old II replies (Candid subtyping decodes the absent optional as None).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RzjuJVat2CTiCYzeU9F6e2
@aterga
aterga merged commit 3ca81d8 into main Jul 5, 2026
1 check 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.

3 participants