pub struct AdminConfig {
pub agent_ids: Vec<String>,
}Expand description
v0.7.0 SHIP cluster (#946 / #957 / #960 / #961, 2026-05-20) —
[admin] top-level block. The operator-configured allowlist of
agent_ids whose authenticated HTTP requests are treated as
admin-class callers, granting full cross-tenant visibility on
endpoints whose payloads necessarily expose corpus-scale
metadata (GET /api/v1/export, GET /api/v1/agents,
GET /api/v1/stats, the POST /api/v1/quota/status list path).
Wire format:
[admin]
agent_ids = ["ops:admin", "ai:claude@workstation"]Default-closed. When the block is absent, the allowlist is
empty and every admin-class endpoint returns 403 Forbidden for
every caller. Operators MUST set [admin].agent_ids = [...]
explicitly to grant any caller admin privileges. This closes
the v0.7.0 SHIP-blocking cross-tenant exfiltration defects
(#946 / #957 / #960) where admin endpoints landed open by default
because the legacy api_key_auth middleware passes through when
no API key is configured.
Caller resolution uses the same primitive other handlers do
(identity::resolve_http_agent_id against X-Agent-Id). The
allowlist matches against the resolved caller string verbatim;
there is no glob / prefix support today (planned under #961 when
the operator surface grows beyond a static list).
Not a substitute for authentication. The role gate runs
AFTER api_key_auth. Deployments serving sensitive corpora
MUST set api_key so the bare-network surface requires the key
AND the role gate runs on top of it. The two layers compose:
api_key_auth answers “is the request authenticated?” and the
admin gate answers “is the authenticated caller an admin?”.
Fields§
§agent_ids: Vec<String>Explicit list of agent_id strings whose authenticated
requests are treated as admin-class. Default vec![]
(empty) means no caller is an admin — every admin-class
endpoint returns 403.
Each entry MUST match a caller’s resolved agent_id
verbatim. Validation: the SAL accepts the same NHI
agent_id charset that
crate::validate::validate_agent_id enforces (see the
“Agent Identity (NHI)” section of CLAUDE.md). Entries that
fail validation at boot are logged at warn and dropped
from the in-memory allowlist; the daemon still starts so
a single typo does not lock the operator out.
Implementations§
Source§impl AdminConfig
impl AdminConfig
Sourcepub fn validated_agent_ids(&self) -> Vec<String>
pub fn validated_agent_ids(&self) -> Vec<String>
Returns the validated subset of agent_ids — entries that
pass crate::validate::validate_agent_id. Entries that
fail validation are dropped (with a warn log) so a single
typo in config.toml cannot lock the operator out.
Trait Implementations§
Source§impl Clone for AdminConfig
impl Clone for AdminConfig
Source§fn clone(&self) -> AdminConfig
fn clone(&self) -> AdminConfig
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for AdminConfig
impl Debug for AdminConfig
Source§impl Default for AdminConfig
impl Default for AdminConfig
Source§fn default() -> AdminConfig
fn default() -> AdminConfig
Source§impl<'de> Deserialize<'de> for AdminConfig
impl<'de> Deserialize<'de> for AdminConfig
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
impl Eq for AdminConfig
Source§impl PartialEq for AdminConfig
impl PartialEq for AdminConfig
Source§fn eq(&self, other: &AdminConfig) -> bool
fn eq(&self, other: &AdminConfig) -> bool
self and other values to be equal, and is used by ==.Source§impl Serialize for AdminConfig
impl Serialize for AdminConfig
impl StructuralPartialEq for AdminConfig
Auto Trait Implementations§
impl Freeze for AdminConfig
impl RefUnwindSafe for AdminConfig
impl Send for AdminConfig
impl Sync for AdminConfig
impl Unpin for AdminConfig
impl UnsafeUnpin for AdminConfig
impl UnwindSafe for AdminConfig
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.impl<T> ErasedDestructor for Twhere
T: 'static,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more