Skip to main content

systemprompt_security/authz/
error.rs

1//! Typed error surface for the authz crate.
2
3use systemprompt_models::domain_error;
4use thiserror::Error;
5
6domain_error! {
7    pub enum AuthzError {
8        common: [repository, validation],
9
10        #[error("invalid rule_type: {0}")]
11        InvalidRuleType(String),
12
13        #[error("invalid access value: {0}")]
14        InvalidAccess(String),
15
16        #[error("authz hook transport: {0}")]
17        Hook(#[from] reqwest::Error),
18
19        #[error("authz bootstrap: {0}")]
20        Bootstrap(#[from] AuthzBootstrapError),
21    }
22}
23
24impl From<sqlx::Error> for AuthzError {
25    fn from(err: sqlx::Error) -> Self {
26        Self::Repository(systemprompt_database::RepositoryError::from(err))
27    }
28}
29
30pub type AuthzResult<T> = Result<T, AuthzError>;
31
32#[derive(Debug, Clone, Error)]
33pub enum AuthzBootstrapError {
34    #[error(
35        "governance.authz.hook.mode = webhook but `url` is missing or blank — refusing to start"
36    )]
37    MissingWebhookUrl,
38
39    #[error("governance.authz.hook.url is invalid or unsafe: {0} — refusing to start")]
40    InvalidWebhookUrl(String),
41
42    #[error(
43        "governance.authz.hook.mode = unrestricted requires `acknowledgement` field equal to the \
44         literal: {expected:?}"
45    )]
46    MissingUnrestrictedAcknowledgement { expected: &'static str },
47
48    #[error(
49        "governance.authz.hook.mode = extension but no extension hook was supplied via \
50         AppContextBuilder::with_authz_hook(...) — refusing to start"
51    )]
52    ExtensionModeButNoHook,
53
54    #[error(
55        "an extension authz hook was supplied via AppContextBuilder::with_authz_hook(...) but \
56         governance.authz.hook.mode is `{mode}` (must be `extension`) — refusing to start"
57    )]
58    ExtensionHookButWrongMode { mode: &'static str },
59
60    #[error(
61        "an extension authz hook was supplied via AppContextBuilder::with_authz_hook(...) but the \
62         profile has no `governance.authz` block — set `governance.authz.hook.mode = extension` \
63         or drop the `with_authz_hook` call"
64    )]
65    NoGovernanceButExtensionHook,
66}