Watch
0
0
Fork
You've already forked hyperhive
0

responder checks the logs or metrics permission per surface

This commit is contained in:
atlas 2026-11-01 17:40:09 +01:00
commit 3b1d118f25
2 changed files with 324 additions and 37 deletions

View file

@ -45,6 +45,7 @@ pub mod github;
pub mod grafana;
pub mod matrix;
pub mod mtls;
pub mod observability;
pub mod path;
pub mod policy;
pub mod proxy;

View file

@ -0,0 +1,62 @@
//! The log and metric read grants: where swarm-controller mirrors an agent's
//! `logs` and `metrics` permissions in the store, and what the object holds.
//!
//! The permissions themselves live in the queue's `agent-permissions` bucket.
//! The store gateways' `swarm-logs-auth` has no queue access, so it reads this
//! mirror instead. A leaf that is absent or unreadable is no grant.
//!
//! Under the agent's own prefix, so the agent can read its own grant and no
//! agent can write it: the shared agent policy grants `create` on one other
//! leaf only.
use serde::{Deserialize, Serialize};
use crate::{
Error,
path::{Kind, principal_prefix},
};
const LEAF: &str = "observability";
/// The path holding `agent`'s [`Grant`].
///
/// # Errors
/// [`Error::PathSegment`] when `agent` contains anything but `[A-Za-z0-9_-]`,
/// which is what keeps one agent's name from addressing another agent's grant.
pub fn grant_path(agent: &str) -> Result<String, Error> {
let prefix = principal_prefix(Kind::Agent, agent)?;
Ok(format!("{prefix}/{LEAF}"))
}
/// What a [`grant_path`] holds: which stores the agent may read.
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct Grant {
/// The agent holds the `logs` permission.
#[serde(default)]
pub logs: bool,
/// The agent holds the `metrics` permission.
#[serde(default)]
pub metrics: bool,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn the_path_is_under_the_agents_own_prefix() {
assert_eq!(
grant_path("atlas").unwrap(),
"swarm/agents/atlas/observability"
);
assert!(grant_path("../argus").is_err());
}
#[test]
fn a_field_left_out_is_not_granted() {
let grant: Grant = serde_json::from_str("{}").unwrap();
assert_eq!(grant, Grant::default());
let grant: Grant = serde_json::from_str(r#"{"logs":true}"#).unwrap();
assert_eq!((grant.logs, grant.metrics), (true, false));
}
}