Skip to content

Azure OIDC for SSH certs: Fetch a list of user groups via Microsoft Graph API #2341

@ryanc-me

Description

@ryanc-me

Hello!

  • Vote on this issue by adding a 👍 reaction
  • If you want to implement this feature, comment to let us know (we'll work with you on design, scheduling, etc.)

Issue details

Allow configuring an extra API endpoint to call as part of the SSH cert issuance process. This info could then be made available to the template file, e.g., as .Custom (here).

A concrete example would be calling the Microsoft Graph API to fetch a list of groups the user belongs to. Then, in the template, we could do something like "Principals": {{ toJson .Custom.groupIds }}.

I haven't looked at other OIDC providers, but this could potentially be generic?

Why is this needed?

Our specific example looks something like this:

  • We have lots of servers (~300 or so)
  • Each server has a single user account
  • Staff are granted access server-by-server

To facilitate that, we're using an Azure OIDC provisioner, with a template like this:

{
	"type": "{{ .Type }}",
	"keyId": "{{ .KeyID }}",
        // the principals will be a list of Azure group IDs
	"principals": {{ toJson .Token.groups }},
	"extensions": {{ toJson .Extensions }},
	"criticalOptions": {{ toJson .CriticalOptions }}
}

Then, we create an Azure group for each server, and place the Object ID of that group into the AuthorizedPrincipalsFile on the server.

The result is: When a user first logs-in, they go through an OAuth login flow, which issues them an SSH cert containing a list of Object IDs of the groups they're in. When they connect to a server, they'll be allowed/denied based on those Group IDs.

This was actually working great, until we hit Azure's 200 group limit for JWTs.

Long story short, if the user has more than 200 groups, Azure will totally omit all groups, and instead suggests to fetch a list of user groups via the Microsoft Graph API (see the ~middle paragraph here). It seems our only option is to fetch a list of groups as a separate API call.

Metadata

Metadata

Assignees

Labels

enhancementneeds triageWaiting for discussion / prioritization by team

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions