Skip to content

test(registry): negative-authorization suite proving owner-only pathsΒ #6

Open

Description

@Meet-hybrid

πŸ’  Sidera β€” Stellar Name Service. Contribute via Drips Wave / GrantFox. Comment with your approach and wait for assignment before starting.

Description

The registry's security story rests on require_auth for owner-only operations (set_address, transfer), but the current tests only prove the positive path with mock_all_auths plus one MockAuth happy-path test. The escrow-style discipline in this ecosystem (soroban-forge's authz.rs) proves that a WRONG signer is rejected by the host, and pins the exact authorized-invocation tree every entrypoint demands. The registry deserves the same rigor β€” this is a name service that will hold valuable identities.

Desired outcome: a dedicated negative-auth test module proving per entrypoint that a non-owner's signature is rejected, and that the auth tree contains exactly the expected invocation.

Scope

  • Crate/module: crates/registry, new src/authz.rs (test module) + mod authz; under #[cfg(test)]
  • API: no changes
  • Storage: none
  • Tests: per-entrypoint wrong-signer rejection; replay/signature-args mismatch rejection; env.auths() tree assertions for register, set_address, transfer
  • Docs: module-level docs explaining the verified mechanics (mirroring the house style)

Non-goals

  • Property/fuzz testing (separate issue)
  • Changes to any entrypoint or storage
  • New dependencies beyond soroban-sdk testutils

What "done" looks like

  • set_address with an impostor signature is rejected by the host (not by our own check first β€” order verified)
  • transfer with a non-owner signer is rejected; the new owner's signature alone is NOT sufficient
  • env.auths() assertions pin the exact authorized-invocation tree for each entrypoint (contract address, fn name, args)
  • A signature armed for one set of args cannot be replayed against different args
  • Module docs explain mock-auth mechanics and why self-authorization is implicit
  • Existing tests stay green; clippy -D warnings clean

Implementation guidelines

  • Reference implementation: soroban-forge's crates/escrow/src/authz.rs (public repo: Meet-hybrid/soroban-forge) β€” same SDK 27, same patterns: MockAuth/MockAuthInvoke for negative cases, env.auths() for tree assertions
  • Use SideraRegistryClient's try_* variants to capture host errors without unwinding
  • Test file organization: one #[test] per entrypoint per scenario, named fn {entrypoint}_{scenario}_is_rejected()
  • Register the module with #[cfg(test)] mod authz; next to the existing mod tests

Verification

cargo fmt --all -- --check
cargo clippy --workspace --all-targets --locked -- -D warnings
cargo test -p sidera-registry --all-targets --locked

PR guidelines

  • Get assigned before starting; do not start work on a reserved issue.
  • Work in a fork; branch off upstream/main; open the PR against Sidera-Protocol/sidera-contracts:main.
  • PR description must include Closes #6.
  • All CI checks must pass; human maintainer review required.

Metadata

  • Affected crates/files: contracts/registry/src/authz.rs (new), src/lib.rs (mod decl)
  • Complexity label: complexity: medium (150 base points)
  • Type labels: test

Activity

  1. added
    testAdding missing tests
    external-contributorsSuitable for contributors outside the maintainer team
    complexity: mediumStandard features or involved bug fixes (150 pts)
    on Sep 24, 2026
  2. Rodrigoue9 commented on Oct 7, 2026

    @Rodrigoue9

    Hi @maintainer! I would love to take on this negative-authorization test suite.

    Architecture & Implementation Plan:

    1. Module Scaffolding:
      • Create contracts/registry/src/authz.rs and expose it under #[cfg(test)] mod authz; in contracts/registry/src/lib.rs.
    2. Negative Authorization Scenarios:
      • set_address_impostor_signature_is_rejected: Call SideraRegistryClient::try_set_address using a non-owner identity via MockAuth/MockAuthInvoke and assert host-level authorization failure before state mutation.
      • transfer_non_owner_signature_is_rejected: Prove that providing only the recipient's signature or an unauthorized party fails host auth.
      • replay_with_mismatched_arguments_is_rejected: Verify that an auth payload constructed for address A cannot be replayed for address B.
    3. Invocation Tree Pinning (env.auths()):
      • Explicitly assert the exact authorized invocation tree on register, set_address, and transfer (contract ID, function symbol, matching args).
    4. Verification & Gates:
      • cargo fmt --all -- --check
      • cargo clippy --workspace --all-targets --locked -- -D warnings
      • cargo test -p sidera-registry --all-targets --locked

    Track Record

    Recently delivered Soroban Rust smart contract PRs with full test coverage and clean CI:

    • Vero-protocol/vero-core-contracts: PR #320 (Ledger sequence getter) & PR #321 (Monotonic task counter).
    • Sorobill/Sorobill-Contract: PR #9 & PR #10.

    Ready to implement and submit immediately upon assignment!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    complexity: mediumStandard features or involved bug fixes (150 pts)external-contributorsSuitable for contributors outside the maintainer teamtestAdding missing tests

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions