cat_gateway/settings/
admin.rs

1//! Command line and environment variable for admin settings
2
3use std::str::FromStr;
4
5use catalyst_types::catalyst_id::{key_rotation::KeyRotation, role_index::RoleId};
6use ed25519_dalek::VerifyingKey;
7
8use super::str_env_var::StringEnvVar;
9
10/// Configuration for the Admin functionality.
11#[derive(Clone)]
12pub(crate) struct EnvVars {
13    /// The Catalyst Signed Document Admin Catalyst ID from the `ADMIN_CATALYST_ID`
14    /// env.
15    admin_key: Option<catalyst_signed_doc::CatalystId>,
16}
17
18impl EnvVars {
19    /// Create a config for Catalyst Signed Document validation configuration.
20    pub(super) fn new() -> Self {
21        let admin_key = string_to_catalyst_id(
22            &StringEnvVar::new_optional("ADMIN_CATALYST_ID", false)
23                .map(|v| v.as_string())
24                .unwrap_or_default(),
25        )
26        .filter(|v| {
27            let is_admin = v.is_admin();
28            if !is_admin {
29                tracing::error!(
30                    cat_id = v.to_string(),
31                    "Admin Catalyst ID must be in the admin format."
32                );
33            }
34            let is_valid_role_and_rotation =
35                v.role_and_rotation() == (RoleId::Role0, KeyRotation::DEFAULT);
36            if !is_valid_role_and_rotation {
37                tracing::error!(
38                    cat_id = v.to_string(),
39                    "Admin Catalyst ID must be role 0 with 0 rotation."
40                );
41            }
42            is_admin && is_valid_role_and_rotation
43        });
44
45        if admin_key.is_none() {
46            tracing::error!("Missing or invalid Catalyst ID for Admin. This is required.");
47        }
48
49        Self { admin_key }
50    }
51
52    /// Returns the Admin's role0 public key if the given Catalyst ID matches with the
53    /// assigned Admin Catalyst ID.
54    pub(crate) fn get_admin_key(
55        &self,
56        cat_id: &catalyst_signed_doc::CatalystId,
57        role: RoleId,
58    ) -> Option<(VerifyingKey, KeyRotation)> {
59        if let Some(ref admin_key) = self.admin_key
60            && cat_id == admin_key
61            && role == RoleId::Role0
62        {
63            return Some((admin_key.role0_pk(), KeyRotation::DEFAULT));
64        }
65
66        None
67    }
68}
69
70/// Convert an Envvar into the Catalyst ID type, `None` if missing or invalid value.
71fn string_to_catalyst_id(s: &str) -> Option<catalyst_signed_doc::CatalystId> {
72    catalyst_signed_doc::CatalystId::from_str(s)
73        .inspect_err(|err| {
74            tracing::error!(
75                err = ?err,
76                "Cannot parse Admin CatalystId entry"
77            );
78        })
79        .ok()
80}