Proposal: Auth #1883
Replies: 4 comments 8 replies
|
Hi @Emantor, on behalf of @pamolloy; The changes above are welcome, but are not clear how the identity->capability look-up would be implemented; if there is a token in the grpc metadata, the encryption of the grpc channel needs to be handled, too. To resolve that, I did a PoF at commit afd2d0f master...gastmaier:labgrid:tls For the client|exporter-side, a new argument The second security concern from my side is ssh key-management, but https://github.com/openpubkey/opkssh seem to provide both OIDC for CI/CD workflows and and SSO for users; so changes to labgrid are also not necessary. We still need to test opkssh + client|exporter ssl to confirm it fully solves the security+encryption needs. |
|
I've got a few questions for understanding:
|
|
Building on top of auth, there could then be an optional |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
To facilitate the use of Labgrid in production environments we propose adding flexible authentication and authorisation functionality. This functionality will be backwards compatible so that Labgrid can continue to run in an insecure way for deployments that do not have security requirements (eg. local usage).
This proposal is dependant on
Proposal: gRPC Refactor. However, this proposal does not reference any of the RPC protocol changes as they are yet to be implemented. The examples in this proposal can become more concrete once those changes are implemented.Implementing authentication and authorisation requires the introduction of the following:
Identity context
The operations supported by
labgrid-coordinator(eg. creating/deleting Places, acquiring/releasing Places, etc.) need to be restricted based on the calling user (the principal).We propose introducing a
ContextVariablethat provides access to the identity of the user and the capabilities they have (see Capability model below).The
ContextVariablewill be set in the Coordinator-side plugin (see Client/Exporter and Coordinator-side plugins for injecting and parsing authentication metadata below) and will be accessible from the RPC method handlers.Capability model
The operations a Labgrid user can perform cannot be restricted only by the type of operation (eg. creating a Place, acquiring a Place, etc.). For example, whether a user can release a Place is determined by whether they are the owner of the Place lock.
For this reason, we propose modelling the actions a user may be granted as capabilities that can be validated as part of the RPC method handler logic.
For example, the release Place operation can be subdivided into the
ReleasePlace_Owned(for releasing Places you own) andReleasePlace_Any(for releasing any Place, regardless of whether you acquired it).Client/Exporter and Coordinator-side plugins for injecting and parsing authentication metadata
With gRPC APIs, authentication information is passed in the gRPC metadata.
We propose a pluggable interface in
labgrid-client/labgrid-exporterfor injecting the authentication into the gRPC metadata and inlabgrid-coordinatorfor reading the metadata and populating the Identity context.Refactoring of existing RPCs to include capabilities checks
The current
labgrid-coordinatorimplementation embeds the authorisation logic into the RPC method handlers, based on the pseudo-identity provided in theStartupDonemessage.We propose refactoring the RPC method handlers to base their authorisation checks on the capabilities of the user, accessible from the identity context.
Identity context
We propose adding a
ContextVariablefor storing the per-request principal information:We propose
Identityas a PythonProtocol, allowing flexibility of implementation by thelabgrid-coordinatorauthentication plugin:Capability model
We propose the following capabilities:
ClientStreamclient_streamClientStream.ExporterStreamexporter_streamExporterStream.AddPlaceadd_placePlace.DeletePlacedelete_placePlace.GetPlacesget_placesPlaces.AddPlaceAliasadd_place_aliasPlace.DeletePlaceAliasdelete_place_aliasPlacealias.SetPlaceTagsset_place_tagsPlacetags.SetPlaceCommentset_place_commentPlace.AddPlaceMatchadd_place_matchResourcematch to aPlace.DeletePlaceMatchdelete_place_matchResourcematch from aPlace.AcquirePlaceacquire_placePlace.ReleasePlacerelease_place_ownedPlacethat is owned by the calling principal.ReleasePlacerelease_place_anyPlace. Effectively the ability to runlabgrid-client release -k.AllowPlaceallow_place_ownedPlacethat is owned by the calling principal.AllowPlaceallow_place_anyPlace.CreateReservationcreate_reservationReservationfor aPlace.CancelReservationcancel_reservation_ownedReservationthat is owned by the calling principal.CancelReservationcancel_reservation_anyReservation.PollReservationpoll_reservationReservation.GetReservationsget_reservationsReservations.The capabilities could be represented as an enumerable:
Client/Exporter and Coordinator-side plugins for injecting and parsing authentication metadata
gRPC metadata is the channel for transmitting authentication metadata. gRPC metadata is comprised of K/V pairs.
We propose a plugin architecture where, for a given identity service:
labgrid-client/labgrid-exporterthat injects the identity service-specific metadata K/V pairslabgrid-coordinatorthat processes the metadata K/V pairs, validates them and, if valid, emits theIdentityfor the principalWe propose Python
Protocols for the plugins below. We propose these as callables to allow plugins to be used in a function-like way.Client/Exporter-side
Coordinator-side
Default plugins
We propose the implementation of default plugin implementations that replicate the current functionality of Labgrid.
For the Client/Exporter-side plugin this will involve the injection of the hostname (and username, for the Client) into the metadata.
For the Coordinator-side plugin, this will involve generating an
Identity-compatible object that uses the hostname/username as theidand a static set ofcapabilitiesthat reflect the current Labgrid behaviour.Refactoring of existing RPCs to include capabilities checks
For RPC methods that have a 1:1 mapping with a Capability, we suggest a method decorator that specifies the Capability (or potentially multiple) required to call the method:
For RPC methods that require more granular access, a decorator is not sufficient and the Capability-checking logic will need to be embedded into the method logic:
All reactions