Skip to content

support having silo-level roles confer fleet-level roles#3349

Merged
davepacheco merged 24 commits into
mainfrom
dap/fleet-delegation
Jun 22, 2023
Merged

support having silo-level roles confer fleet-level roles#3349
davepacheco merged 24 commits into
mainfrom
dap/fleet-delegation

Conversation

@davepacheco

@davepacheco davepacheco commented Jun 12, 2023

Copy link
Copy Markdown
Collaborator

Fixes #3275 using Option 3.

Notes about the change:

  • A bunch of stuff moved between various Nexus-internal crates. The definitions of the FleetRole, SiloRole, and ProjectRole enums had to move to nexus/types so that I could some of them in params::SiloCreate. But their impls of DatabaseString couldn't move there, which meant it had to move to nexus/db-model instead (where that trait is defined). So I also moved test_database_string_impl() there so that the tests would live with those impls. This also necessitated moving some expected test output files around.
  • During authentication for the external API, we have to load the user's Silo so that we can get the policy information that now comes from the Silo. This gets glued into the authn::Context as a SiloAuthnPolicy.
  • The SiloAuthnPolicy is also plumbed into the AuthenticatedActor that we hand over to Oso so that it can be used during authorization.
  • I've changed rack initialization to no longer grant "fleet admin" directly to the initial user, but instead use this mechanism to grant "fleet admin" to any admin of the recovery Silo.

This whole mechanism is less general than I thought it would be because care must be taken to load the Silo (to get its policy) before we get to the authorization phase, and that needs to happen using Nexus's own credentials. If we try to load the Silo during authorization using the user's credentials, we'd enter infinite recursion because loading the Silo requires Fleet-level privileges. The net result is that if we ever want to do this kind of thing with some resource other than the Silo, we'll need to do something more sophisticated.

@davepacheco davepacheco marked this pull request as ready for review June 16, 2023 22:19
@davepacheco davepacheco requested a review from luqmana June 21, 2023 16:01

@luqmana luqmana left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for tackling this @davepacheco! Looks mostly good. I did have one question about doing a check in the polar vs rust.

Also, there's no way currently modify a Silo right? Which means a conferred role can't be removed without deleting + recreating the Silo?

Comment thread nexus/db-model/src/lib.rs Outdated
Comment thread nexus/db-queries/src/authz/api_resources.rs Outdated
Comment thread nexus/db-queries/src/authz/omicron.polar
Comment thread nexus/db-queries/src/db/datastore/rack.rs Outdated
Comment thread nexus/db-queries/src/db/datastore/rack.rs Outdated
@davepacheco

Copy link
Copy Markdown
Collaborator Author

Also, there's no way currently modify a Silo right? Which means a conferred role can't be removed without deleting + recreating the Silo?

That's correct. The role also can't be added without deleting and recreating the Silo. I don't think there's anything too tricky about implementing a Silo update that supports changing this. The big thing to remember when we do that is someone will probably need to have Fleet-level permissions to change this particular property of the Silo.

@luqmana

luqmana commented Jun 22, 2023

Copy link
Copy Markdown
Contributor

Also, there's no way currently modify a Silo right? Which means a conferred role can't be removed without deleting + recreating the Silo?

That's correct. The role also can't be added without deleting and recreating the Silo. I don't think there's anything too tricky about implementing a Silo update that supports changing this. The big thing to remember when we do that is someone will probably need to have Fleet-level permissions to change this particular property of the Silo.

Ok, that matches what I thought. I definitely do think we should have a way to modify this for an existing Silo. Let's open a bug for that?

@davepacheco

Copy link
Copy Markdown
Collaborator Author

Filed #3400.

@davepacheco davepacheco enabled auto-merge (squash) June 22, 2023 20:22
@davepacheco davepacheco merged commit 6d9cbf1 into main Jun 22, 2023
@davepacheco davepacheco deleted the dap/fleet-delegation branch June 22, 2023 21:07
Comment thread openapi/nexus.json
},
"uniqueItems": true
}
},

@david-crespo david-crespo Jun 26, 2023

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just noticed while integrating this into the console that this is probably wrong. I don't think Dropshot is handling BTreeMap correctly. I will look into it further.

/// Mapping of which Fleet roles are conferred by each Silo role
///
/// The default is that no Fleet roles are conferred by any Silo roles
/// unless there's a corresponding entry in this map.
pub mapped_fleet_roles:
BTreeMap<shared::SiloRole, BTreeSet<shared::FleetRole>>,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm, maybe it is right. I guess the keys can't be type-constrained, but we are correctly specifying the type of the values as an array of FleetRole where the items are unique. Ok!

https://swagger.io/docs/specification/data-models/dictionaries/

I will look at improving the TS client generator to handle this.

@david-crespo david-crespo Jun 26, 2023

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we wanted to be slightly more elaborate and more correct, instead of unconstrained string keys, maybe we could do the OpenAPI analogue of this TS type:

mapped_fleet_role: {
  viewer?: Set<FleetRole>,
  collaborator?: Set<FleetRole>,
  admin?: Set<FleetRole>,
}

i.e., a hard-coded set of keys, all of which are optional. It's probably fine for now. In the console, the user is going to be choosing these roles from a menu, so it will be hard to pass in something that doesn't exist.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

want way to delegate Fleet access

3 participants