Skip to content
Open
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
2 changes: 2 additions & 0 deletions Cargo.lock

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

8 changes: 8 additions & 0 deletions nexus/auth/src/authz/api_resources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1429,3 +1429,11 @@ authz_resource! {
roles_allowed = false,
polar_snippet = Custom,
}

authz_resource! {
name = "ScimClientBearerToken",
parent = "Silo",
primary_key = Uuid,
roles_allowed = false,
polar_snippet = Custom,
}
38 changes: 37 additions & 1 deletion nexus/auth/src/authz/omicron.polar
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ resource Fleet {
"viewer",

# Internal-only roles
"external-authenticator"
"external-authenticator",
"external-scim"
];

# Roles implied by other roles on this resource
Expand Down Expand Up @@ -149,6 +150,9 @@ resource Silo {
# external authenticator has to create silo users
"list_children" if "external-authenticator" on "parent_fleet";
"create_child" if "external-authenticator" on "parent_fleet";

# external scim has to be able to read SCIM tokens
"list_children" if "external-scim" on "parent_fleet";
}

has_relation(fleet: Fleet, "parent_fleet", silo: Silo)
Expand Down Expand Up @@ -703,3 +707,35 @@ resource AlertClassList {

has_relation(fleet: Fleet, "parent_fleet", collection: AlertClassList)
if collection.fleet = fleet;

# These rules grant the external scim authenticator role the permission
# required to create the SCIM provider implementation for a Silo

has_permission(actor: AuthenticatedActor, "read", silo: Silo)
if has_role(actor, "external-scim", silo.fleet);

resource ScimClientBearerToken {
permissions = [
"read",
"modify",
"create_child",
"list_children",
];
relations = { parent_silo: Silo, parent_fleet: Fleet };

# Silo-level roles grant privileges for SCIM client tokens.
"read" if "admin" on "parent_silo";
"list_children" if "admin" on "parent_silo";
"modify" if "admin" on "parent_silo";
"create_child" if "admin" on "parent_silo";

# Fleet-level roles also grant privileges for SCIM client tokens.
"read" if "admin" on "parent_fleet";
"list_children" if "admin" on "parent_fleet";
"modify" if "admin" on "parent_fleet";
"create_child" if "admin" on "parent_fleet";
}
has_relation(silo: Silo, "parent_silo", scim_client_bearer_token: ScimClientBearerToken)
if scim_client_bearer_token.silo = silo;
has_relation(fleet: Fleet, "parent_fleet", collection: ScimClientBearerToken)
if collection.silo.fleet = fleet;
1 change: 1 addition & 0 deletions nexus/auth/src/authz/oso_generic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ pub fn make_omicron_oso(log: &slog::Logger) -> Result<OsoInit, anyhow::Error> {
Zpool::init(),
Service::init(),
UserBuiltin::init(),
ScimClientBearerToken::init(),
];

for init in generated_inits {
Expand Down
21 changes: 21 additions & 0 deletions nexus/db-lookup/src/lookup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,18 @@ impl<'a> LookupPath<'a> {
{
Alert::PrimaryKey(Root { lookup_root: self }, id)
}

/// Select a resource of type [`ScimClientBearerToken`], identified by its
/// UUID.
pub fn scim_client_bearer_token_id<'b>(
self,
id: Uuid,
) -> ScimClientBearerToken<'b>
where
'a: 'b,
{
ScimClientBearerToken::PrimaryKey(Root { lookup_root: self }, id)
}
}

/// Represents the head of the selection path for a resource
Expand Down Expand Up @@ -909,6 +921,15 @@ lookup_resource! {
]
}

lookup_resource! {
name = "ScimClientBearerToken",
ancestors = ["Silo"],
lookup_by_name = false,
soft_deletes = true,
primary_key_columns = [ { column_name = "id", rust_type = Uuid } ],
visible_outside_silo = true
}

// Helpers for unifying the interfaces around images

pub enum ImageLookup<'a> {
Expand Down
2 changes: 2 additions & 0 deletions nexus/db-model/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ mod producer_endpoint;
mod project;
mod reconfigurator_config;
mod rendezvous_debug_dataset;
mod scim_client_bearer_token;
mod semver_version;
mod serde_time_delta;
mod silo_auth_settings;
Expand Down Expand Up @@ -223,6 +224,7 @@ pub use rendezvous_debug_dataset::*;
pub use role_assignment::*;
pub use saga_types::*;
pub use schema_versions::*;
pub use scim_client_bearer_token::*;
pub use semver_version::*;
pub use service_kind::*;
pub use silo::*;
Expand Down
3 changes: 2 additions & 1 deletion nexus/db-model/src/schema_versions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use std::{collections::BTreeMap, sync::LazyLock};
///
/// This must be updated when you change the database schema. Refer to
/// schema/crdb/README.adoc in the root of this repository for details.
pub const SCHEMA_VERSION: Version = Version::new(197, 0, 0);
pub const SCHEMA_VERSION: Version = Version::new(198, 0, 0);

/// List of all past database schema versions, in *reverse* order
///
Expand All @@ -28,6 +28,7 @@ static KNOWN_VERSIONS: LazyLock<Vec<KnownVersion>> = LazyLock::new(|| {
// | leaving the first copy as an example for the next person.
// v
// KnownVersion::new(next_int, "unique-dirname-with-the-sql-files"),
KnownVersion::new(198, "scim-client-bearer-token"),
KnownVersion::new(197, "scim-users-and-groups"),
KnownVersion::new(196, "user-provision-type-for-silo-user-and-group"),
KnownVersion::new(195, "tuf-pruned-index"),
Expand Down
53 changes: 53 additions & 0 deletions nexus/db-model/src/scim_client_bearer_token.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// 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/.

use chrono::DateTime;
use chrono::Utc;
use nexus_db_schema::schema::scim_client_bearer_token;
use nexus_types::external_api::views;
use uuid::Uuid;

/// A SCIM client sends requests to a SCIM provider (in this case, Nexus) using
/// some sort of authentication. Nexus currently only supports Bearer token auth
/// from SCIM clients, and these tokens are stored here.
#[derive(Queryable, Insertable, Clone, Debug, Selectable)]
#[diesel(table_name = scim_client_bearer_token)]
pub struct ScimClientBearerToken {
pub id: Uuid,

pub time_created: DateTime<Utc>,
pub time_deleted: Option<DateTime<Utc>>,
pub time_expires: Option<DateTime<Utc>>,

pub silo_id: Uuid,

pub bearer_token: String,
}

impl ScimClientBearerToken {
pub fn id(&self) -> Uuid {
self.id
}
}

impl From<ScimClientBearerToken> for views::ScimClientBearerToken {
fn from(t: ScimClientBearerToken) -> views::ScimClientBearerToken {
views::ScimClientBearerToken {
id: t.id,
time_created: t.time_created,
time_expires: t.time_expires,
}
}
}

impl From<ScimClientBearerToken> for views::ScimClientBearerTokenValue {
fn from(t: ScimClientBearerToken) -> views::ScimClientBearerTokenValue {
views::ScimClientBearerTokenValue {
id: t.id,
time_created: t.time_created,
time_expires: t.time_expires,
bearer_token: t.bearer_token,
}
}
}
2 changes: 2 additions & 0 deletions nexus/db-queries/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ diesel.workspace = true
diesel-dtrace.workspace = true
dropshot.workspace = true
futures.workspace = true
hex.workspace = true
id-map.workspace = true
iddqd.workspace = true
internal-dns-resolver.workspace = true
Expand All @@ -39,6 +40,7 @@ rand.workspace = true
ref-cast.workspace = true
regex.workspace = true
schemars.workspace = true
scim2-rs.workspace = true
semver.workspace = true
serde.workspace = true
serde_json.workspace = true
Expand Down
3 changes: 3 additions & 0 deletions nexus/db-queries/src/db/datastore/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ pub mod region_snapshot_replacement;
mod rendezvous_debug_dataset;
mod role;
mod saga;
mod scim;
mod scim_provider_store;
mod silo;
mod silo_auth_settings;
mod silo_group;
Expand Down Expand Up @@ -143,6 +145,7 @@ pub use region::RegionAllocationFor;
pub use region::RegionAllocationParameters;
pub use region_snapshot_replacement::NewRegionVolumeId;
pub use region_snapshot_replacement::OldSnapshotVolumeId;
pub use scim_provider_store::CrdbScimProviderStore;
pub use silo::Discoverability;
pub use silo_group::SiloGroup;
pub use silo_group::SiloGroupApiOnly;
Expand Down
Loading
Loading