diff --git a/crank-counter/anchor/programs/crank-counter/src/lib.rs b/crank-counter/anchor/programs/crank-counter/src/lib.rs index 2e0c5a6f..c5b789bc 100644 --- a/crank-counter/anchor/programs/crank-counter/src/lib.rs +++ b/crank-counter/anchor/programs/crank-counter/src/lib.rs @@ -30,6 +30,9 @@ pub mod anchor_counter { Ok(()) } + // This example intentionally keeps `increment` permissionless. A privileged scheduled + // instruction must authenticate the preceding Hydra `Trigger` through the instructions + // sysvar. Scheduled instructions run top-level and do not inherit a Hydra PDA signature. /// Increment the counter. pub fn increment(ctx: Context) -> Result<()> { let counter = &mut ctx.accounts.counter; diff --git a/delegation-actions/anchor/programs/delegation-actions/src/lib.rs b/delegation-actions/anchor/programs/delegation-actions/src/lib.rs index 20636ff8..6c8b48b7 100644 --- a/delegation-actions/anchor/programs/delegation-actions/src/lib.rs +++ b/delegation-actions/anchor/programs/delegation-actions/src/lib.rs @@ -22,6 +22,9 @@ pub mod delegation_actions { Ok(()) } + // This example intentionally keeps `increment` permissionless. A privileged + // post-delegation action should require an action signer that was validated and recorded + // when the account was delegated, or check an authority stored in program state. pub fn increment(ctx: Context) -> Result<()> { let counter = &mut ctx.accounts.counter; counter.count += 1; diff --git a/magic-actions/anchor/programs/magic-actions/src/lib.rs b/magic-actions/anchor/programs/magic-actions/src/lib.rs index 2944a823..f13dfe05 100644 --- a/magic-actions/anchor/programs/magic-actions/src/lib.rs +++ b/magic-actions/anchor/programs/magic-actions/src/lib.rs @@ -127,6 +127,10 @@ pub struct Increment<'info> { pub counter: Account<'info, Counter>, } + // `#[action]` adds the action accounts but does not authenticate the caller. + // This example intentionally leaves `update_leaderboard` public. A privileged handler + // must constrain `escrow_auth` to an expected authority and require the derived `escrow` + // PDA as a signer, or require an authority stored in program state. #[action] #[derive(Accounts)] pub struct UpdateLeaderboard<'info> { diff --git a/roll-dice/pinocchio/programs/roll-dice-delegated/src/processor.rs b/roll-dice/pinocchio/programs/roll-dice-delegated/src/processor.rs index cb6b584f..98438ca6 100644 --- a/roll-dice/pinocchio/programs/roll-dice-delegated/src/processor.rs +++ b/roll-dice/pinocchio/programs/roll-dice-delegated/src/processor.rs @@ -124,6 +124,12 @@ pub fn process_callback_roll_dice( return Err(ProgramError::InvalidSeeds); } + // The scoped identity address is public. Its signer privilege proves that the + // VRF program invoked this callback. + if !program_identity.is_signer() { + return Err(ProgramError::MissingRequiredSignature); + } + let rnd_u8 = random_u8_with_range(&randomness, 1, 6); pinocchio_log::log!("Consuming random number: {}", rnd_u8); pinocchio_log::log!("client_seed={}", client_seed); diff --git a/roll-dice/pinocchio/programs/roll-dice/src/processor.rs b/roll-dice/pinocchio/programs/roll-dice/src/processor.rs index 1e1d1834..f88c4a5f 100644 --- a/roll-dice/pinocchio/programs/roll-dice/src/processor.rs +++ b/roll-dice/pinocchio/programs/roll-dice/src/processor.rs @@ -118,6 +118,12 @@ pub fn process_callback_roll_dice( return Err(ProgramError::InvalidSeeds); } + // The scoped identity address is public. Its signer privilege proves that the + // VRF program invoked this callback. + if !program_identity.is_signer() { + return Err(ProgramError::MissingRequiredSignature); + } + let rnd_u8 = random_u8_with_range(&randomness, 1, 6); pinocchio_log::log!("Consuming random number: {}", rnd_u8); pinocchio_log::log!("client_seed={}", client_seed);