Skip to main content

bitwarden_access_token/
kind.rs

1//! The client-kind segment of an access token.
2
3use bitwarden_access_token_crypto::KeyPurpose;
4
5/// Which kind of unattended client a [`crate::AccessToken`] authenticates.
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum AccessTokenKind {
8    /// The PAM access connector.
9    AccessConnector,
10    /// Secrets Manager, whose tokens have no client-kind segment.
11    SecretsManager,
12}
13
14impl AccessTokenKind {
15    /// The `<client-kind>` wire segment, or `None` if the format omits it.
16    pub fn segment(&self) -> Option<&'static str> {
17        match self {
18            Self::AccessConnector => Some("access-connector"),
19            Self::SecretsManager => None,
20        }
21    }
22
23    /// The key-derivation purpose. `SecretsManager`'s must match the web vault, which mints Secrets
24    /// Manager tokens independently.
25    pub fn key_purpose(&self) -> KeyPurpose {
26        match self {
27            Self::AccessConnector => KeyPurpose::AccessConnector,
28            Self::SecretsManager => KeyPurpose::SecretsManager,
29        }
30    }
31}
32
33#[cfg(test)]
34mod tests {
35    use super::*;
36
37    /// Must match the server's `PamAccessConnectorClientProvider.AccessConnectorPrefix`, or tokens
38    /// parse but cannot authenticate.
39    #[test]
40    fn access_connector_matches_the_servers_provider_prefix() {
41        assert_eq!(
42            AccessTokenKind::AccessConnector.segment(),
43            Some("access-connector")
44        );
45    }
46
47    #[test]
48    fn secrets_manager_has_no_segment() {
49        assert_eq!(AccessTokenKind::SecretsManager.segment(), None);
50    }
51
52    /// The strings themselves are pinned in `bitwarden-access-token-crypto`.
53    #[test]
54    fn key_purposes_are_pinned() {
55        assert_eq!(
56            AccessTokenKind::SecretsManager.key_purpose(),
57            KeyPurpose::SecretsManager
58        );
59        assert_eq!(
60            AccessTokenKind::AccessConnector.key_purpose(),
61            KeyPurpose::AccessConnector
62        );
63    }
64}