Skip to content

feat(api): Extend audit logging for all gas sponsorship actions #9

Description

@Emmyt24

Description

The audit log system in crates/api/src/audit.rs currently records wallet, withdrawal, and auth actions. Gas sponsorship introduces three new auditable categories:

  1. Sponsorship configuration changed (enabled/disabled, fee cap or budget updated).
  2. A sponsored transaction was submitted (with outcome: confirmed or failed).
  3. Sponsorship rejected due to policy (invalid XDR, forbidden op type, budget exceeded).

Every one of these events must appear in the audit log so account owners can review exactly when and by whom gas sponsorship was used or misconfigured.

Requirements and Context

  • Add a new SPONSORSHIP constant to the audit category list in crates/api/src/audit.rs (alongside the existing WITHDRAWAL, WALLET, etc.).
  • All three event types must capture: user_id (derived from the API key's wallet owner), ip_address (from request headers), action string (human-readable), category: SPONSORSHIP, and target (set to the wallet_id).
  • For rejected requests (bad XDR, budget exceeded) the audit entry must be recorded even though the HTTP response is an error — so abuse attempts leave a trail.
  • The record function signature in crates/api/src/audit.rs already accepts these fields; no new Store methods are needed.

Suggested Execution

Branch: feat/gas-sponsorship/audit-logging

Implement Changes

  • Add to crates/api/src/audit.rs:
    pub mod category {
        pub const SPONSORSHIP: &str = "sponsorship";
        // existing constants remain unchanged
    }
  • In crates/api/src/routes/sponsor.rs, call crate::audit::record for:
    • Successful submission: "sponsored a transaction (confirmed)" or "sponsored a transaction (failed)".
    • Policy rejection: "sponsor request rejected: <reason>" where reason is one of xdr_invalid, op_not_allowed, budget_exceeded, sponsorship_disabled.
  • In crates/api/src/routes/sponsorship.rs, call crate::audit::record on every successful PUT: "updated sponsorship config (enabled: <true|false>)".
  • Audit recording is best-effort — wrap each call in the existing let _ = ... pattern so failures never propagate to the caller.

Test and Commit

  • Tests in crates/api/tests/api_tests.rs:
    • audit_records_sponsorship_config_change — PUT sponsorship config; query audit logs for category sponsorship and assert the action string is present.
    • audit_records_rejected_sponsor_request — send invalid XDR; assert a sponsor request rejected: xdr_invalid log entry was created.
    • audit_records_confirmed_sponsored_tx — run the happy path; assert a sponsored a transaction (confirmed) entry.
  • Run cargo test -p octo-api.

Example Commit Message

feat(api): add SPONSORSHIP audit log category and record all sponsor events

Records config changes, submission outcomes, and policy rejections in the
audit log. Rejected requests also generate entries so abuse attempts are
always traceable.

Guidelines

  • The audit entry for a rejected request must be recorded before returning the error response.
  • Do not log the raw XDR in the audit action string — it may be large; log the inner tx hash if available after parsing, otherwise just the rejection reason.
  • Reference this issue with Closes #<issue-number> in the PR description.

Metadata

Metadata

Assignees

Labels

GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial CampaignCampaign: Official Campaign

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions