Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

54 changes: 54 additions & 0 deletions nexus/external-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use nexus_types_versions::v2026_01_01_00;
use nexus_types_versions::v2026_01_03_00;
use nexus_types_versions::v2026_01_05_00;
use nexus_types_versions::v2026_01_08_00;
use nexus_types_versions::v2026_01_15_00;
use nexus_types_versions::v2026_01_16_00;
use nexus_types_versions::v2026_01_16_01;
use nexus_types_versions::v2026_01_22_00;
Expand Down Expand Up @@ -7774,6 +7775,7 @@ pub trait NexusExternalApi {
method = GET,
path = "/v1/system/audit-log",
tags = ["system/audit-log"],
versions = VERSION_AUDIT_LOG_CREDENTIAL_ID..,
}]
async fn audit_log_list(
rqctx: RequestContext<Self::Context>,
Expand All @@ -7785,6 +7787,58 @@ pub trait NexusExternalApi {
HttpError,
>;

/// View audit log
#[endpoint {
operation_id = "audit_log_list",
method = GET,
path = "/v1/system/audit-log",
tags = ["system/audit-log"],
versions = VERSION_AUDIT_LOG_AUTH_METHOD_ENUM..VERSION_AUDIT_LOG_CREDENTIAL_ID,
}]
async fn audit_log_list_v2026_01_15_00(
rqctx: RequestContext<Self::Context>,
query_params: Query<
PaginatedByTimeAndId<latest::audit::AuditLogParams>,
>,
) -> Result<
HttpResponseOk<ResultsPage<v2026_01_15_00::audit::AuditLogEntry>>,
HttpError,
> {
let page = Self::audit_log_list(rqctx, query_params).await?.0;
Ok(HttpResponseOk(ResultsPage {
items: page.items.into_iter().map(Into::into).collect(),
next_page: page.next_page,
}))
}

/// View audit log
#[endpoint {
operation_id = "audit_log_list",
method = GET,
path = "/v1/system/audit-log",
tags = ["system/audit-log"],
versions = ..VERSION_AUDIT_LOG_AUTH_METHOD_ENUM,
}]
async fn audit_log_list_v2025_11_20_00(
rqctx: RequestContext<Self::Context>,
query_params: Query<
PaginatedByTimeAndId<latest::audit::AuditLogParams>,
>,
) -> Result<
HttpResponseOk<ResultsPage<v2025_11_20_00::audit::AuditLogEntry>>,
HttpError,
> {
let page = Self::audit_log_list(rqctx, query_params).await?.0;
Ok(HttpResponseOk(ResultsPage {
items: page
.items
.into_iter()
.map(|e| v2026_01_15_00::audit::AuditLogEntry::from(e).into())
.collect(),
next_page: page.next_page,
}))
}

// Console API: logins

/// SAML login console page (just a link to the IdP)
Expand Down
96 changes: 96 additions & 0 deletions nexus/types/versions/src/audit_log_auth_method_enum/audit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

//! Audit log types for version AUDIT_LOG_AUTH_METHOD_ENUM.

use chrono::{DateTime, Utc};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::net::IpAddr;
use uuid::Uuid;

use crate::v2025_11_20_00::audit::{AuditLogEntryActor, AuditLogEntryResult};

/// Authentication method used for a request
#[derive(
Debug, Clone, Copy, Deserialize, Serialize, JsonSchema, PartialEq, Eq,
)]
#[serde(rename_all = "snake_case")]
pub enum AuthMethod {
/// Console session cookie
SessionCookie,
/// Device access token (OAuth 2.0 device authorization flow)
AccessToken,
/// SCIM client bearer token
ScimToken,
/// Spoof authentication (test only)
#[schemars(skip)]
Spoof,
}

impl AuthMethod {
/// Returns the wire-format name used by older API versions that exposed
/// `auth_method` as a free-form string.
fn as_str(self) -> &'static str {
match self {
AuthMethod::SessionCookie => "session_cookie",
AuthMethod::AccessToken => "access_token",
AuthMethod::ScimToken => "scim_token",
AuthMethod::Spoof => "spoof",
}
}
}

/// Audit log entry
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct AuditLogEntry {
/// Unique identifier for the audit log entry
pub id: Uuid,

/// When the request was received
pub time_started: DateTime<Utc>,

/// Request ID for tracing requests through the system
pub request_id: String,
/// URI of the request, truncated to 512 characters. Will only include
/// host and scheme for HTTP/2 requests. For HTTP/1.1, the URI will
/// consist of only the path and query.
pub request_uri: String,
/// API endpoint ID, e.g., `project_create`
pub operation_id: String,
/// IP address that made the request
pub source_ip: IpAddr,
/// User agent string from the request, truncated to 256 characters.
pub user_agent: Option<String>,

pub actor: AuditLogEntryActor,

/// How the user authenticated the request (access token, session, or SCIM
/// token). Null for unauthenticated requests like login attempts.
pub auth_method: Option<AuthMethod>,

/// Time operation completed
pub time_completed: DateTime<Utc>,

/// Result of the operation
pub result: AuditLogEntryResult,
}

impl From<AuditLogEntry> for crate::v2025_11_20_00::audit::AuditLogEntry {
fn from(new: AuditLogEntry) -> Self {
Self {
id: new.id,
time_started: new.time_started,
request_id: new.request_id,
request_uri: new.request_uri,
operation_id: new.operation_id,
source_ip: new.source_ip,
user_agent: new.user_agent,
actor: new.actor,
auth_method: new.auth_method.map(|m| m.as_str().to_string()),
time_completed: new.time_completed,
result: new.result,
}
}
}
10 changes: 10 additions & 0 deletions nexus/types/versions/src/audit_log_auth_method_enum/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

//! Version `AUDIT_LOG_AUTH_METHOD_ENUM` of the Nexus external API.
//!
//! Changes the audit log `auth_method` field from a free-form string to a typed
//! `AuthMethod` enum.

pub mod audit;
36 changes: 19 additions & 17 deletions nexus/types/versions/src/audit_log_credential_id/audit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,7 @@ use std::net::IpAddr;
use uuid::Uuid;

use crate::v2025_11_20_00::audit::{AuditLogEntryActor, AuditLogEntryResult};

/// Authentication method used for a request
#[derive(
Debug, Clone, Copy, Deserialize, Serialize, JsonSchema, PartialEq, Eq,
)]
#[serde(rename_all = "snake_case")]
pub enum AuthMethod {
/// Console session cookie
SessionCookie,
/// Device access token (OAuth 2.0 device authorization flow)
AccessToken,
/// SCIM client bearer token
ScimToken,
/// Spoof authentication (test only)
#[schemars(skip)]
Spoof,
}
use crate::v2026_01_15_00::audit::AuthMethod;

/// Audit log entry
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
Expand Down Expand Up @@ -68,3 +52,21 @@ pub struct AuditLogEntry {
/// Result of the operation
pub result: AuditLogEntryResult,
}

impl From<AuditLogEntry> for crate::v2026_01_15_00::audit::AuditLogEntry {
fn from(new: AuditLogEntry) -> Self {
Self {
id: new.id,
time_started: new.time_started,
request_id: new.request_id,
request_uri: new.request_uri,
operation_id: new.operation_id,
source_ip: new.source_ip,
user_agent: new.user_agent,
actor: new.actor,
auth_method: new.auth_method,
time_completed: new.time_completed,
result: new.result,
}
}
}
2 changes: 1 addition & 1 deletion nexus/types/versions/src/audit_log_credential_id/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@

//! Version `AUDIT_LOG_CREDENTIAL_ID` of the Nexus external API.
//!
//! Adds `AuthMethod` enum and `credential_id` to audit log entries.
//! Adds `credential_id` to audit log entries.

pub mod audit;
3 changes: 2 additions & 1 deletion nexus/types/versions/src/latest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,9 @@ pub mod audit {
pub use crate::v2025_11_20_00::audit::AuditLogEntryResult;
pub use crate::v2025_11_20_00::audit::AuditLogParams;

pub use crate::v2026_01_15_00::audit::AuthMethod;

pub use crate::v2026_01_15_01::audit::AuditLogEntry;
pub use crate::v2026_01_15_01::audit::AuthMethod;
}

pub mod bfd {
Expand Down
2 changes: 2 additions & 0 deletions nexus/types/versions/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ pub mod v2026_01_03_00;
pub mod v2026_01_05_00;
#[path = "multicast_implicit_lifecycle_updates/mod.rs"]
pub mod v2026_01_08_00;
#[path = "audit_log_auth_method_enum/mod.rs"]
pub mod v2026_01_15_00;
#[path = "audit_log_credential_id/mod.rs"]
pub mod v2026_01_15_01;
#[path = "rename_address_selector_to_address_allocator/mod.rs"]
Expand Down
Loading