spire_api/
selectors.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
//! Selectors conforming to SPIRE standards.
use crate::proto::spire::api::types::Selector as SpiffeSelector;

const K8S_TYPE: &str = "k8s";
const UNIX_TYPE: &str = "unix";

/// Converts user-defined selectors into SPIFFE selectors.
impl From<Selector> for SpiffeSelector {
    fn from(s: Selector) -> SpiffeSelector {
        match s {
            Selector::K8s(k8s_selector) => SpiffeSelector {
                r#type: K8S_TYPE.to_string(),
                value: k8s_selector.into(),
            },
            Selector::Unix(unix_selector) => SpiffeSelector {
                r#type: UNIX_TYPE.to_string(),
                value: unix_selector.into(),
            },
            Selector::Generic((k, v)) => SpiffeSelector {
                r#type: k,
                value: v,
            },
        }
    }
}

#[derive(Debug, Clone)]
/// Represents various types of SPIFFE identity selectors.
pub enum Selector {
    /// Represents a SPIFFE identity selector based on Kubernetes constructs.
    K8s(K8s),
    /// Represents a SPIFFE identity selector based on Unix system constructs such as PID, GID, and UID.
    Unix(Unix),
    /// Represents a generic SPIFFE identity selector defined by a key-value pair.
    Generic((String, String)),
}

const K8S_SA_TYPE: &str = "sa";
const K8S_NS_TYPE: &str = "ns";

/// Converts Kubernetes selectors to their string representation.
impl From<K8s> for String {
    fn from(k: K8s) -> String {
        match k {
            K8s::ServiceAccount(s) => format!("{}:{}", K8S_SA_TYPE, s),
            K8s::Namespace(s) => format!("{}:{}", K8S_NS_TYPE, s),
        }
    }
}

#[derive(Debug, Clone)]
/// Represents a SPIFFE identity selector for Kubernetes.
pub enum K8s {
    /// SPIFFE identity selector for a Kubernetes service account.
    ServiceAccount(String),
    /// SPIFFE identity selector for a Kubernetes namespace.
    Namespace(String),
}

const UNIX_PID_TYPE: &str = "pid";
const UNIX_GID_TYPE: &str = "gid";
const UNIX_UID_TYPE: &str = "uid";

/// Converts a Unix selector into a formatted string representation.
impl From<Unix> for String {
    fn from(value: Unix) -> Self {
        match value {
            Unix::Pid(s) => format!("{}:{}", UNIX_PID_TYPE, s),
            Unix::Gid(s) => format!("{}:{}", UNIX_GID_TYPE, s),
            Unix::Uid(s) => format!("{}:{}", UNIX_UID_TYPE, s),
        }
    }
}

#[derive(Debug, Clone)]
/// Represents SPIFFE identity selectors based on Unix process-related attributes.
pub enum Unix {
    /// Specifies a selector for a Unix process ID (PID).
    Pid(u16),
    /// Specifies a selector for a Unix group ID (GID).
    Gid(u16),
    /// Specifies a selector for a Unix user ID (UID).
    Uid(u16),
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_k8s_sa_selector() {
        let selector = Selector::K8s(K8s::ServiceAccount("foo".to_string()));
        let spiffe_selector: SpiffeSelector = selector.into();
        assert_eq!(spiffe_selector.r#type, K8S_TYPE);
        assert_eq!(spiffe_selector.value, "sa:foo");
    }

    #[test]
    fn test_k8s_ns_selector() {
        let selector = Selector::K8s(K8s::Namespace("foo".to_string()));
        let spiffe_selector: SpiffeSelector = selector.into();
        assert_eq!(spiffe_selector.r#type, K8S_TYPE);
        assert_eq!(spiffe_selector.value, "ns:foo");
    }

    #[test]
    fn test_unix_pid_selector() {
        let selector = Selector::Unix(Unix::Pid(500));
        let spiffe_selector: SpiffeSelector = selector.into();
        assert_eq!(spiffe_selector.r#type, UNIX_TYPE);
        assert_eq!(spiffe_selector.value, "pid:500");
    }

    #[test]
    fn test_unix_gid_selector() {
        let selector = Selector::Unix(Unix::Gid(500));
        let spiffe_selector: SpiffeSelector = selector.into();
        assert_eq!(spiffe_selector.r#type, UNIX_TYPE);
        assert_eq!(spiffe_selector.value, "gid:500");
    }

    #[test]
    fn test_unix_uid_selector() {
        let selector = Selector::Unix(Unix::Uid(500));
        let spiffe_selector: SpiffeSelector = selector.into();
        assert_eq!(spiffe_selector.r#type, UNIX_TYPE);
        assert_eq!(spiffe_selector.value, "uid:500");
    }
}