securitydept_token_set_context/access_token_substrate/propagation/
config.rs1use regex::Regex;
2use serde::{Deserialize, Serialize};
3use typed_builder::TypedBuilder;
4
5#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
7#[serde(rename_all = "snake_case")]
8pub enum BearerPropagationPolicy {
9 ValidateThenForward,
12 ExchangeForDownstreamToken,
18}
19
20pub(crate) fn default_bearer_propagation_policy() -> BearerPropagationPolicy {
21 BearerPropagationPolicy::ValidateThenForward
22}
23
24fn default_true() -> bool {
25 true
26}
27
28#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, TypedBuilder)]
30pub struct TokenPropagatorConfig {
31 #[builder(default = BearerPropagationPolicy::ValidateThenForward)]
33 #[serde(default = "default_bearer_propagation_policy")]
34 pub default_policy: BearerPropagationPolicy,
35 #[builder(default)]
37 #[serde(default)]
38 pub destination_policy: PropagationDestinationPolicy,
39 #[builder(default)]
41 #[serde(default)]
42 pub token_validation: PropagatedTokenValidationConfig,
43}
44
45impl Default for TokenPropagatorConfig {
46 fn default() -> Self {
47 Self {
48 default_policy: default_bearer_propagation_policy(),
49 destination_policy: PropagationDestinationPolicy::default(),
50 token_validation: PropagatedTokenValidationConfig::default(),
51 }
52 }
53}
54
55#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default, TypedBuilder)]
57pub struct PropagationDestinationPolicy {
58 #[builder(default)]
60 #[serde(default)]
61 pub allowed_node_ids: Vec<String>,
62 #[builder(default)]
64 #[serde(default)]
65 pub allowed_targets: Vec<AllowedPropagationTarget>,
66 #[builder(default = true)]
70 #[serde(default = "default_true")]
71 pub deny_sensitive_ip_literals: bool,
72 #[builder(default = true)]
75 #[serde(default = "default_true")]
76 pub require_explicit_port: bool,
77}
78
79#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
81#[serde(rename_all = "snake_case")]
82pub enum PropagationScheme {
83 Https,
84 Http,
85}
86
87impl PropagationScheme {
88 pub fn as_str(&self) -> &'static str {
89 match self {
90 Self::Https => "https",
91 Self::Http => "http",
92 }
93 }
94}
95
96#[derive(Debug, Clone, Serialize, Deserialize)]
98#[serde(tag = "kind", rename_all = "snake_case")]
99pub enum AllowedPropagationTarget {
100 ExactOrigin {
102 scheme: PropagationScheme,
103 hostname: String,
104 port: u16,
105 },
106 DomainSuffix {
108 scheme: PropagationScheme,
109 domain_suffix: String,
110 port: u16,
111 },
112 DomainRegex {
114 scheme: PropagationScheme,
115 #[serde(with = "serde_regex")]
116 domain_regex: Regex,
117 port: u16,
118 },
119 Cidr {
121 scheme: PropagationScheme,
122 cidr: String,
123 port: u16,
124 },
125}
126
127impl PartialEq for AllowedPropagationTarget {
128 fn eq(&self, other: &Self) -> bool {
129 match (self, other) {
130 (
131 Self::ExactOrigin {
132 scheme: left_scheme,
133 hostname: left_hostname,
134 port: left_port,
135 },
136 Self::ExactOrigin {
137 scheme: right_scheme,
138 hostname: right_hostname,
139 port: right_port,
140 },
141 ) => {
142 left_scheme == right_scheme
143 && left_hostname == right_hostname
144 && left_port == right_port
145 }
146 (
147 Self::DomainSuffix {
148 scheme: left_scheme,
149 domain_suffix: left_suffix,
150 port: left_port,
151 },
152 Self::DomainSuffix {
153 scheme: right_scheme,
154 domain_suffix: right_suffix,
155 port: right_port,
156 },
157 ) => {
158 left_scheme == right_scheme
159 && left_suffix == right_suffix
160 && left_port == right_port
161 }
162 (
163 Self::DomainRegex {
164 scheme: left_scheme,
165 domain_regex: left_regex,
166 port: left_port,
167 },
168 Self::DomainRegex {
169 scheme: right_scheme,
170 domain_regex: right_regex,
171 port: right_port,
172 },
173 ) => {
174 left_scheme == right_scheme
175 && left_regex.as_str() == right_regex.as_str()
176 && left_port == right_port
177 }
178 (
179 Self::Cidr {
180 scheme: left_scheme,
181 cidr: left_cidr,
182 port: left_port,
183 },
184 Self::Cidr {
185 scheme: right_scheme,
186 cidr: right_cidr,
187 port: right_port,
188 },
189 ) => left_scheme == right_scheme && left_cidr == right_cidr && left_port == right_port,
190 _ => false,
191 }
192 }
193}
194
195impl Eq for AllowedPropagationTarget {}
196
197#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default, TypedBuilder)]
200pub struct PropagatedTokenValidationConfig {
201 #[builder(default)]
203 #[serde(default)]
204 pub required_issuers: Vec<String>,
205 #[builder(default)]
207 #[serde(default)]
208 pub allowed_audiences: Vec<String>,
209 #[builder(default)]
211 #[serde(default)]
212 pub required_scopes: Vec<String>,
213 #[builder(default)]
215 #[serde(default)]
216 pub allowed_azp: Vec<String>,
217}