fix(registry): make owner Signer to prevent update_field signer privilege escalation (#4)#6
Open
nanookclaw wants to merge 1 commit intocascade-protocol:mainfrom
Conversation
…calation Fixes cascade-protocol#4: register_agent failed with 'signer privilege escalated' when owner != payer and additional_metadata was non-empty. Root cause: spl_token_metadata_interface::instruction::update_field marks the update_authority (owner) as a required signer: AccountMeta::new_readonly(*update_authority, true) The previous UncheckedAccount<'info> for owner had is_signer = false, so the Solana runtime rejected the CPI with: Cross-program invocation with unauthorized signer or writable account Fix: Change owner from UncheckedAccount<'info> to Signer<'info>. The update_authority is always the owner (set in step 2f initialize_metadata), so requiring owner to sign is semantically correct — they are authorising the registration of their own agent NFT. Client behaviour (unchanged for common case): - owner == payer: pass payer pubkey for both accounts; no extra signer - owner != payer: include owner as an additional signer in the transaction Tests added: - test_register_agent_owner_not_payer_metadata_key_too_long_correct_error: verifies owner != payer + metadata reaches validation (not signer bug) - test_register_agent_owner_equals_payer_metadata_key_too_long_correct_error: verifies owner == payer path still works after the Signer change
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Closes #4.
register_agentfails withCross-program invocation with unauthorized signer or writable accountwhen both conditions are true:owner != payer(minting on behalf of a different wallet)additional_metadatais provided (non-null, non-empty)Root cause
Step 2g calls
spl_token_metadata_interface::instruction::update_fieldwithowneras theupdate_authority. That instruction marks the update_authority as a required signer:But
ownerwas declared asUncheckedAccount<'info>, which means itsAccountInfohasis_signer = false. The Solana runtime detects the mismatch and rejects with:The default path (
owner == payer) was unaffected becausepayer: Signer<'info>already hadis_signer = true, which propagated to both account slots.Fix
Change
ownerfromUncheckedAccount<'info>toSigner<'info>.This is semantically correct:
owneris always the metadata update authority (set in step 2f'sinitialize_metadatacall). Requiring the owner to sign authorises registration of their own agent NFT.Client behaviour
owner == payerowner != payer, no metadataowner != payer, with metadataTests
Two regression tests added to
programs/sati/tests/registry/register_agent.rs:test_register_agent_owner_not_payer_metadata_key_too_long_correct_error— owner != payer, owner included as signer; transaction reaches input validation (MetadataKeyTooLong) rather than the signer escalation bug. Asserts the error does not contain "signer privilege".test_register_agent_owner_equals_payer_metadata_key_too_long_correct_error— owner == payer; verifies the common path still works after the Signer change.The full success-path integration test requires a Token-2022 devnet environment with
update_fielddispatch; the TypeScript SDK tests cover that path.