Skip to main content

road_runner_common/
capabilities.rs

1//! Account-level capabilities (entitlements) shared across services.
2//!
3//! Distinct from API-key [`crate::permissions`] (per key) and roles (operational). A user is
4//! granted a default set at registration; the platform admin can restrict/grant per user. The
5//! effective set is computed in the identity service and propagated to every service as the
6//! signed `x-auth-capabilities` header; enforcement is per-endpoint via
7//! [`crate::UserContext::require_capability`].
8
9/// Read account data (balances / orders / history).
10pub const ACCOUNT_READ: &str = "account.read";
11/// Place / cancel spot orders.
12pub const SPOT_TRADE: &str = "spot.trade";
13/// Crypto deposits.
14pub const DEPOSIT_CRYPTO: &str = "deposit.crypto";
15/// Crypto withdrawals.
16pub const WITHDRAW_CRYPTO: &str = "withdraw.crypto";
17/// Internal transfers.
18pub const TRANSFER_INTERNAL: &str = "transfer.internal";
19/// Create / use API keys.
20pub const API_ACCESS: &str = "api.access";
21/// Fiat deposits.
22pub const FIAT_DEPOSIT: &str = "fiat.deposit";
23/// Fiat withdrawals.
24pub const FIAT_WITHDRAW: &str = "fiat.withdraw";
25
26/// Every known capability, in canonical order.
27pub const ALL: &[&str] = &[
28    ACCOUNT_READ,
29    SPOT_TRADE,
30    DEPOSIT_CRYPTO,
31    WITHDRAW_CRYPTO,
32    TRANSFER_INTERNAL,
33    API_ACCESS,
34    FIAT_DEPOSIT,
35    FIAT_WITHDRAW,
36];
37
38/// Capabilities granted to every user at registration. Several of these (see the
39/// consuming service's KYC gate) are still hard-blocked until KYC clears — being
40/// "default on" only means no admin action is required once it does.
41pub const DEFAULT_ON: &[&str] = &[
42    ACCOUNT_READ,
43    SPOT_TRADE,
44    DEPOSIT_CRYPTO,
45    WITHDRAW_CRYPTO,
46    TRANSFER_INTERNAL,
47    API_ACCESS,
48    FIAT_DEPOSIT,
49    FIAT_WITHDRAW,
50];
51
52/// True when `cap` is a recognized capability.
53pub fn is_valid(cap: &str) -> bool {
54    ALL.contains(&cap)
55}
56
57/// True when `cap` is on by default at registration.
58pub fn is_default_on(cap: &str) -> bool {
59    DEFAULT_ON.contains(&cap)
60}