spire_api/
selectors.rs

1//! Selectors conforming to SPIRE standards.
2use crate::proto::spire::api::types::Selector as SpiffeSelector;
3
4const K8S_TYPE: &str = "k8s";
5const UNIX_TYPE: &str = "unix";
6
7/// Converts user-defined selectors into SPIFFE selectors.
8impl From<Selector> for SpiffeSelector {
9    fn from(s: Selector) -> SpiffeSelector {
10        match s {
11            Selector::K8s(k8s_selector) => SpiffeSelector {
12                r#type: K8S_TYPE.to_string(),
13                value: k8s_selector.into(),
14            },
15            Selector::Unix(unix_selector) => SpiffeSelector {
16                r#type: UNIX_TYPE.to_string(),
17                value: unix_selector.into(),
18            },
19            Selector::Generic((k, v)) => SpiffeSelector {
20                r#type: k,
21                value: v,
22            },
23        }
24    }
25}
26
27#[derive(Debug, Clone)]
28/// Represents various types of SPIFFE identity selectors.
29pub enum Selector {
30    /// Represents a SPIFFE identity selector based on Kubernetes constructs.
31    K8s(K8s),
32    /// Represents a SPIFFE identity selector based on Unix system constructs such as PID, GID, and UID.
33    Unix(Unix),
34    /// Represents a generic SPIFFE identity selector defined by a key-value pair.
35    Generic((String, String)),
36}
37
38const K8S_SA_TYPE: &str = "sa";
39const K8S_NS_TYPE: &str = "ns";
40
41/// Converts Kubernetes selectors to their string representation.
42impl From<K8s> for String {
43    fn from(k: K8s) -> String {
44        match k {
45            K8s::ServiceAccount(s) => format!("{K8S_SA_TYPE}:{s}"),
46            K8s::Namespace(s) => format!("{K8S_NS_TYPE}:{s}"),
47        }
48    }
49}
50
51#[derive(Debug, Clone)]
52/// Represents a SPIFFE identity selector for Kubernetes.
53pub enum K8s {
54    /// SPIFFE identity selector for a Kubernetes service account.
55    ServiceAccount(String),
56    /// SPIFFE identity selector for a Kubernetes namespace.
57    Namespace(String),
58}
59
60const UNIX_PID_TYPE: &str = "pid";
61const UNIX_GID_TYPE: &str = "gid";
62const UNIX_UID_TYPE: &str = "uid";
63
64/// Converts a Unix selector into a formatted string representation.
65impl From<Unix> for String {
66    fn from(value: Unix) -> Self {
67        match value {
68            Unix::Pid(s) => format!("{UNIX_PID_TYPE}:{s}"),
69            Unix::Gid(s) => format!("{UNIX_GID_TYPE}:{s}"),
70            Unix::Uid(s) => format!("{UNIX_UID_TYPE}:{s}"),
71        }
72    }
73}
74
75#[derive(Debug, Clone)]
76/// Represents SPIFFE identity selectors based on Unix process-related attributes.
77pub enum Unix {
78    /// Specifies a selector for a Unix process ID (PID).
79    Pid(u16),
80    /// Specifies a selector for a Unix group ID (GID).
81    Gid(u16),
82    /// Specifies a selector for a Unix user ID (UID).
83    Uid(u16),
84}
85
86#[cfg(test)]
87mod tests {
88    use super::*;
89
90    #[test]
91    fn test_k8s_sa_selector() {
92        let selector = Selector::K8s(K8s::ServiceAccount("foo".to_string()));
93        let spiffe_selector: SpiffeSelector = selector.into();
94        assert_eq!(spiffe_selector.r#type, K8S_TYPE);
95        assert_eq!(spiffe_selector.value, "sa:foo");
96    }
97
98    #[test]
99    fn test_k8s_ns_selector() {
100        let selector = Selector::K8s(K8s::Namespace("foo".to_string()));
101        let spiffe_selector: SpiffeSelector = selector.into();
102        assert_eq!(spiffe_selector.r#type, K8S_TYPE);
103        assert_eq!(spiffe_selector.value, "ns:foo");
104    }
105
106    #[test]
107    fn test_unix_pid_selector() {
108        let selector = Selector::Unix(Unix::Pid(500));
109        let spiffe_selector: SpiffeSelector = selector.into();
110        assert_eq!(spiffe_selector.r#type, UNIX_TYPE);
111        assert_eq!(spiffe_selector.value, "pid:500");
112    }
113
114    #[test]
115    fn test_unix_gid_selector() {
116        let selector = Selector::Unix(Unix::Gid(500));
117        let spiffe_selector: SpiffeSelector = selector.into();
118        assert_eq!(spiffe_selector.r#type, UNIX_TYPE);
119        assert_eq!(spiffe_selector.value, "gid:500");
120    }
121
122    #[test]
123    fn test_unix_uid_selector() {
124        let selector = Selector::Unix(Unix::Uid(500));
125        let spiffe_selector: SpiffeSelector = selector.into();
126        assert_eq!(spiffe_selector.r#type, UNIX_TYPE);
127        assert_eq!(spiffe_selector.value, "uid:500");
128    }
129}