Skip to content

Commit c72216f

Browse files
committed
rebase
Created using jj-spr 0.1.0
2 parents 339fe9c + 200beb8 commit c72216f

File tree

62 files changed

+32244
-802
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+32244
-802
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

common/src/api/external/mod.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -284,8 +284,6 @@ impl TryFrom<String> for Name {
284284
}
285285

286286
impl FromStr for Name {
287-
// TODO: We should have better error types here.
288-
// See https://github.com/oxidecomputer/omicron/issues/347
289287
type Err = String;
290288

291289
fn from_str(value: &str) -> Result<Self, Self::Err> {
@@ -376,8 +374,6 @@ impl TryFrom<String> for NameOrId {
376374
}
377375

378376
impl FromStr for NameOrId {
379-
// TODO: We should have better error types here.
380-
// See https://github.com/oxidecomputer/omicron/issues/347
381377
type Err = String;
382378

383379
fn from_str(value: &str) -> Result<Self, Self::Err> {

key-manager/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,3 @@ thiserror.workspace = true
1818
tokio.workspace = true
1919
zeroize.workspace = true
2020
omicron-workspace-hack.workspace = true
21-

key-manager/src/lib.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -306,18 +306,23 @@ pub enum SecretRetrieverError {
306306

307307
#[error("Bootstore error: {0}")]
308308
Bootstore(String),
309+
310+
#[error("Trust quorum error: {0}")]
311+
TrustQuorum(String),
309312
}
310313

311314
/// A mechanism for retrieving a secrets to use as input key material to HKDF-
312315
/// Extract.
313316
#[async_trait]
314-
pub trait SecretRetriever {
317+
pub trait SecretRetriever: Send + Sync + 'static {
315318
/// Return the latest secret
316319
////
317320
/// This is useful when a new entity is being encrypted and there is no need
318321
/// for a reconfiguration. When an entity is already encrypted, and needs to
319322
/// be decrypted, the user should instead call the [`SecretRetriever::get`].
320-
async fn get_latest(&self) -> Result<VersionedIkm, SecretRetrieverError>;
323+
async fn get_latest(
324+
&mut self,
325+
) -> Result<VersionedIkm, SecretRetrieverError>;
321326

322327
/// Get the secret for the given epoch
323328
///
@@ -331,7 +336,7 @@ pub trait SecretRetriever {
331336
/// Return an error if its not possible to recover the old secret given the
332337
/// latest secret.
333338
async fn get(
334-
&self,
339+
&mut self,
335340
epoch: u64,
336341
) -> Result<SecretState, SecretRetrieverError>;
337342
}
@@ -363,15 +368,15 @@ mod tests {
363368
#[async_trait]
364369
impl SecretRetriever for TestSecretRetriever {
365370
async fn get_latest(
366-
&self,
371+
&mut self,
367372
) -> Result<VersionedIkm, SecretRetrieverError> {
368373
let salt = [0u8; 32];
369374
let (epoch, bytes) = self.ikms.last_key_value().unwrap();
370375
Ok(VersionedIkm::new(*epoch, salt, bytes))
371376
}
372377

373378
async fn get(
374-
&self,
379+
&mut self,
375380
epoch: u64,
376381
) -> Result<SecretState, SecretRetrieverError> {
377382
let salt = [0u8; 32];

nexus/auth/src/authn/external/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ mod test {
237237
OK => SchemeResult::Authenticated(authn::Details {
238238
actor: self.actor,
239239
device_token_expiration: None,
240+
credential_id: None,
240241
}),
241242
FAIL => SchemeResult::Failed(Reason::BadCredentials {
242243
actor: self.actor,

nexus/auth/src/authn/external/scim.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use crate::authn;
1212
use async_trait::async_trait;
1313
use headers::HeaderMapExt;
1414
use headers::authorization::{Authorization, Bearer};
15+
use uuid::Uuid;
1516

1617
// This scheme is intended only for SCIM provisioning clients.
1718
//
@@ -66,9 +67,10 @@ where
6667
Ok(None) => SchemeResult::NotRequested,
6768
Ok(Some(token)) => match ctx.scim_token_actor(token).await {
6869
Err(error) => SchemeResult::Failed(error),
69-
Ok(actor) => SchemeResult::Authenticated(Details {
70+
Ok((actor, token_id)) => SchemeResult::Authenticated(Details {
7071
actor,
7172
device_token_expiration: None,
73+
credential_id: Some(token_id),
7274
}),
7375
},
7476
}
@@ -93,10 +95,11 @@ fn parse_token(
9395
}
9496

9597
/// A context that can look up a Actor::Scim from a token.
98+
/// Returns the actor and the SCIM token ID.
9699
#[async_trait]
97100
pub trait ScimTokenContext {
98101
async fn scim_token_actor(
99102
&self,
100103
token: String,
101-
) -> Result<authn::Actor, Reason>;
104+
) -> Result<(authn::Actor, Uuid), Reason>;
102105
}

nexus/auth/src/authn/external/session_cookie.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use dropshot::HttpError;
1414
use http::HeaderValue;
1515
use nexus_types::authn::cookies::parse_cookies;
1616
use omicron_uuid_kinds::ConsoleSessionUuid;
17+
use omicron_uuid_kinds::GenericUuid;
1718
use omicron_uuid_kinds::SiloUserUuid;
1819
use slog::debug;
1920
use uuid::Uuid;
@@ -183,6 +184,7 @@ where
183184
SchemeResult::Authenticated(Details {
184185
actor,
185186
device_token_expiration: None,
187+
credential_id: Some(session.id().into_untyped_uuid()),
186188
})
187189
}
188190
}

nexus/auth/src/authn/external/spoof.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ where
112112
SchemeResult::Authenticated(Details {
113113
actor,
114114
device_token_expiration: None,
115+
credential_id: None, // spoof auth has no real credential
115116
})
116117
}
117118
}

nexus/auth/src/authn/external/token.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use async_trait::async_trait;
1414
use chrono::{DateTime, Utc};
1515
use headers::HeaderMapExt;
1616
use headers::authorization::{Authorization, Bearer};
17+
use uuid::Uuid;
1718

1819
// This scheme is intended for clients such as the API, CLI, etc.
1920
//
@@ -66,10 +67,11 @@ where
6667
Ok(None) => SchemeResult::NotRequested,
6768
Ok(Some(token)) => match ctx.authenticate_token(token).await {
6869
Err(error) => SchemeResult::Failed(error),
69-
Ok((actor, device_token_expiration)) => {
70+
Ok((actor, device_token_expiration, token_id)) => {
7071
SchemeResult::Authenticated(Details {
7172
actor,
7273
device_token_expiration,
74+
credential_id: Some(token_id),
7375
})
7476
}
7577
},
@@ -97,12 +99,12 @@ fn parse_token(
9799
/// A context that can look up a Silo user and client ID from a token.
98100
#[async_trait]
99101
pub trait TokenContext {
100-
/// Returns the actor authenticated by the token and the token's expiration
101-
/// time (if any).
102+
/// Returns the actor authenticated by the token, the token's expiration
103+
/// time (if any), and the token's ID.
102104
async fn authenticate_token(
103105
&self,
104106
token: String,
105-
) -> Result<(authn::Actor, Option<DateTime<Utc>>), Reason>;
107+
) -> Result<(authn::Actor, Option<DateTime<Utc>>, Uuid), Reason>;
106108
}
107109

108110
#[cfg(test)]

nexus/auth/src/authn/mod.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,20 @@ impl Context {
108108
}
109109
}
110110

111+
/// Returns the ID of the credential used to authenticate, if any.
112+
///
113+
/// For session auth, this is the session ID. For access token auth, this is
114+
/// the token ID. For SCIM auth, this is the SCIM token ID.
115+
/// Not set for spoof auth, built-in users, or unauthenticated requests.
116+
pub fn credential_id(&self) -> Option<Uuid> {
117+
match &self.kind {
118+
Kind::Authenticated(Details { credential_id, .. }, ..) => {
119+
*credential_id
120+
}
121+
Kind::Unauthenticated => None,
122+
}
123+
}
124+
111125
/// Returns the current actor's Silo if they have one or an appropriate
112126
/// error otherwise
113127
///
@@ -234,6 +248,7 @@ impl Context {
234248
Details {
235249
actor: Actor::UserBuiltin { user_builtin_id },
236250
device_token_expiration: None,
251+
credential_id: None,
237252
},
238253
None,
239254
),
@@ -253,6 +268,7 @@ impl Context {
253268
silo_id: USER_TEST_PRIVILEGED.silo_id,
254269
},
255270
device_token_expiration: None,
271+
credential_id: None,
256272
},
257273
Some(SiloAuthnPolicy::try_from(&*DEFAULT_SILO).unwrap()),
258274
),
@@ -283,6 +299,7 @@ impl Context {
283299
Details {
284300
actor: Actor::SiloUser { silo_user_id, silo_id },
285301
device_token_expiration: None,
302+
credential_id: None,
286303
},
287304
Some(silo_authn_policy),
288305
),
@@ -298,6 +315,7 @@ impl Context {
298315
Details {
299316
actor: Actor::Scim { silo_id },
300317
device_token_expiration: None,
318+
credential_id: None,
301319
},
302320
// This should never be non-empty, we don't want the SCIM user
303321
// to ever have associated roles.
@@ -415,12 +433,15 @@ enum Kind {
415433
#[derive(Clone, Debug, Deserialize, Serialize)]
416434
pub struct Details {
417435
/// the actor performing the request
418-
actor: Actor,
436+
pub actor: Actor,
419437
/// When the device token expires. Present only when authenticating via
420438
/// a device token. This is a slightly awkward fit but is included here
421439
/// because we need to use this to clamp the expiration time when device
422440
/// tokens are confirmed using an existing device token.
423-
device_token_expiration: Option<DateTime<Utc>>,
441+
pub device_token_expiration: Option<DateTime<Utc>>,
442+
/// ID of the credential used to authenticate (session ID, access token ID,
443+
/// or SCIM token ID). Not set for spoof auth or built-in users.
444+
pub credential_id: Option<Uuid>,
424445
}
425446

426447
/// Who is performing an operation

0 commit comments

Comments
 (0)