pnp / cli-microsoft365

Manage Microsoft 365 and SharePoint Framework projects on any platform
https://aka.ms/cli-m365
MIT License
886 stars 314 forks source link

New command: 'm365 entra pim role assignment add' - Request activation of an Entra role assignment #5766

Closed martinlingstuyl closed 3 months ago

martinlingstuyl commented 6 months ago

The first hurdle in the PIM space: requesting activation of a role. By default it will request activation of a role assignment for the current user. But it's also possible to request activation as an admin for another user.

Usage

m365 entra pim role assignment add [options]

Description

Request activation of an Entra ID role assignment for a user or group.

Options

Option Description
-n, --roleDefinitionName [roleDefinitionName] Name of the role definition that should be assigned. Specify either roleDefinitionName or roleDefinitionId but not both.
-i, --roleDefinitionId [roleDefinitionId] Id of the role definition that is being assigned. Specify either roleDefinitionName or roleDefinitionId but not both.
--userId [userId] Id of the user that will be granted the assignment. Specify either userId, userName, groupId or groupName. If not specified, the current user will be used.
--userName [userName] UPN of the user that will be granted the assignment. Specify either userId, userName, groupId or groupName. If not specified, the current user will be used.
--groupId [groupId] Id of the group that will be granted the assignment. Specify either userId, userName, groupId or groupName. If not specified, the current user will be used.
--groupName [groupName] Display name of the group that will be granted the assignment. Specify either userId, userName, groupId or groupName. If not specified, the current user will be used.
--directoryScopeId [directoryScopeId] Id of the directory object representing the scope of the assignment. Will default to tenant-wide scope if not specified.
-j, --justification [justification] An optional justification message.
-s, --startDateTime [startDateTime] When the assignment should start. If left out, the assignment will start from the current time.
-e, --endDateTime [endDateTime] When the assignment should end. Specify either duration or endDateTime.
-d, --duration [duration] How long the assignment should last. Write in ISO 8601 format for durations: PT3H for 3 hours.
--ticketNumber [ticketNumber] Optional ticket number value to communicate with the request.
--ticketSystem [ticketSystem] Optional ticket system to communicate with the request.

Examples

Request activation of the SharePoint Administrator Entra ID role assignment for the current user.

m365 entra pim role assignment add --roleDefinitionName 'SharePoint Administrator'

Request activation of an Entra ID role assignment for the current user.

m365 entra pim role assignment add --roleDefinitionId 'f1417aa3-bf0b-4cc5-a845-a0b2cf11f690'

Request activation of an Entra ID role assignment for the current user with a justification and max duration of 4 hours.

m365 entra pim role assignment add --roleDefinitionId 'f1417aa3-bf0b-4cc5-a845-a0b2cf11f690' --justification 'Need Global Admin to release application xyz to production' --duration 'PT4H'

Request activation of an Entra ID role assignment for a specified user.

m365 entra pim role assignment add --roleDefinitionId 'f1417aa3-bf0b-4cc5-a845-a0b2cf11f690' --userId '3488d6b8-6b2e-41c3-9583-1991205323c2'

Request activation of an Entra ID role assignment for a specific period of two days.

m365 entra pim role assignment add --roleDefinitionName 'Global Administrator' --userId 'admin-john@contoso.com' --startDateTime '2024-01-10T09:00:00Z' --endDateTime '2024-01-11T17:00:00Z'

Response

{
    "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#roleManagement/directory/roleAssignmentScheduleRequests/$entity",
    "id": "911bab8a-6912-4de2-9dc0-2648ede7dd6d",
    "status": "Granted",
    "createdDateTime": "2022-04-13T08:52:32.6485851Z",
    "completedDateTime": "2022-04-14T00:00:00Z",
    "approvalId": null,
    "customData": null,
    "action": "selfActivate",
    "principalId": "071cc716-8147-4397-a5ba-b2105951cc0b",
    "roleDefinitionId": "8424c6f0-a189-499e-bbd0-26c1753c96d4",
    "directoryScopeId": "/",
    "appScopeId": null,
    "isValidationOnly": false,
    "targetScheduleId": "911bab8a-6912-4de2-9dc0-2648ede7dd6d",
    "justification": "I need access to the Attribute Administrator role to manage attributes to be assigned to restricted AUs",
    "createdBy": {
        "application": null,
        "device": null,
        "user": {
            "displayName": null,
            "id": "071cc716-8147-4397-a5ba-b2105951cc0b"
        }
    },
    "scheduleInfo": {
        "startDateTime": "2022-04-14T00:00:00Z",
        "recurrence": null,
        "expiration": {
            "type": "afterDuration",
            "endDateTime": null,
            "duration": "PT5H"
        }
    },
    "ticketInfo": {
        "ticketNumber": "CONTOSO:Normal-67890",
        "ticketSystem": "MS Project"
    }
}

Additional information

The value of the 'action' property of the request object should be either adminAssign or selfActivate, depending on if any of the userId, userName etc options are used.

Needs Entra permission scopes "RoleAssignmentSchedule.ReadWrite.Directory" and/or "RoleManagement.Read.Directory" OR "Directory.ReadWrite.All" which we already may have.

https://learn.microsoft.com/en-us/graph/api/rbacapplication-post-roleassignmentschedulerequests?view=graph-rest-1.0&tabs=http

If --roleDefinitionName is used, the CLI should search for the role definition by name using the endpoint:

https://graph.microsoft.com/v1.0/roleManagement/directory/roleDefinitions?$filter=displayName eq 'SharePoint Administrator'&$select=id

First specs, created for 'm365 entra pim roleassignment request add' ### Usage m365 entra pim roleassignment request add [options] ### Description Request activation of an Entra ID role assignment for a user or group. ### Options Option | Description -- | -- `-n, --roleDefinitionName [roleDefinitionName]` | Name of the role definition that should be assigned. Specify either `roleDefinitionName` or `roleDefinitionId` but not both. `-i, --roleDefinitionId [roleDefinitionId]` | Id of the role definition that is being assigned. Specify either `roleDefinitionName` or `roleDefinitionId` but not both. `-p, --principalId [principalId]` | Id of the user or group that has been granted the assignment. Will default to the Id of the signed-in user if not specified. Is required when running in app-only mode. `-a, --action [action]` | Represents the type of the role assignment request. Allowed values are: `adminAssign`, `adminUpdate`, `adminRemove`, `selfActivate`, `selfDeactivate`, `adminExtend`, `adminRenew`, `selfExtend`, `selfRenew`. Defaults to `selfActivate`. `-d, --directoryScopeId [directoryScopeId]` | Id of the directory object representing the scope of the assignment. Specify either `directoryScopeId` or `appScopeId`. If none is specified, will default to tenant-wide scope. `--appScopeId [appScopeId]` | Id of an app-specific scope. Specify either `directoryScopeId` or `appScopeId`. If none is specified, will default to tenant-wide scope. `-j, --justification [justification]` | An optional justification message. `-s, --startDateTime [startDateTime]` | When the assignment should start. If left out, the assignment will start from the current time. `-d, --duration [duration]` | How long the assignment should last. Write in ISO 8601 format for durations: PT3H for 3 hours. `--ticketNumber [ticketNumber]` | Optional ticket number value to communicate with the request. `--ticketSystem [ticketSystem]` | Optional ticket system to communicate with the request. ### Remarks Use the `principalId` option to request a role assignment for other users or groups. Only use actions `selfActivate` and `selfDeactivate` when not specifying `principalId`. ### Examples Request activation of the _SharePoint Administrator_ Entra ID role assignment for the current user. ```sh m365 entra pim roleassignment request add --roleDefinitionName 'SharePoint Administrator' ``` Request activation of an Entra ID role assignment for the current user. ```sh m365 entra pim roleassignment request add --roleDefinitionId 'f1417aa3-bf0b-4cc5-a845-a0b2cf11f690' ``` Request activation of an Entra ID role assignment for the current user with a justification and max duration of 4 hours. ```sh m365 entra pim roleassignment request add --roleDefinitionId 'f1417aa3-bf0b-4cc5-a845-a0b2cf11f690' --justification 'Need Global Admin to release application xyz to production' --duration 'PT4H' ``` Request activation of an Entra ID role assignment for a specified user. ```sh m365 entra pim roleassignment request add --roleDefinitionId 'f1417aa3-bf0b-4cc5-a845-a0b2cf11f690' --action adminAssign --principalId '3488d6b8-6b2e-41c3-9583-1991205323c2' ``` ### Response ```json { "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#roleManagement/directory/roleAssignmentScheduleRequests/$entity", "id": "911bab8a-6912-4de2-9dc0-2648ede7dd6d", "status": "Granted", "createdDateTime": "2022-04-13T08:52:32.6485851Z", "completedDateTime": "2022-04-14T00:00:00Z", "approvalId": null, "customData": null, "action": "selfActivate", "principalId": "071cc716-8147-4397-a5ba-b2105951cc0b", "roleDefinitionId": "8424c6f0-a189-499e-bbd0-26c1753c96d4", "directoryScopeId": "/", "appScopeId": null, "isValidationOnly": false, "targetScheduleId": "911bab8a-6912-4de2-9dc0-2648ede7dd6d", "justification": "I need access to the Attribute Administrator role to manage attributes to be assigned to restricted AUs", "createdBy": { "application": null, "device": null, "user": { "displayName": null, "id": "071cc716-8147-4397-a5ba-b2105951cc0b" } }, "scheduleInfo": { "startDateTime": "2022-04-14T00:00:00Z", "recurrence": null, "expiration": { "type": "afterDuration", "endDateTime": null, "duration": "PT5H" } }, "ticketInfo": { "ticketNumber": "CONTOSO:Normal-67890", "ticketSystem": "MS Project" } } ``` ### Additional information Needs Entra permission scopes "RoleAssignmentSchedule.ReadWrite.Directory" and/or "RoleManagement.Read.Directory" OR "Directory.ReadWrite.All" which we already may have. https://learn.microsoft.com/en-us/graph/api/rbacapplication-post-roleassignmentschedulerequests?view=graph-rest-1.0&tabs=http If `--roleDefinitionName` is used, the CLI should search for the role definition by name using the endpoint: https://graph.microsoft.com/v1.0/roleManagement/directory/roleDefinitions?$filter=displayName eq 'SharePoint Administrator'&$select=id
Jwaegebaert commented 6 months ago

Looks good @martinlingstuyl. Let's ship it.

martinlingstuyl commented 6 months ago

Could you give it an additional review @Jwaegebaert? I changed some things, like added a --roleDefinitionName option, some extra shorts and extra Additional Information.

waldekmastykarz commented 5 months ago

I suggest we remove -t because it's ambiguous between the ticket ID and system

martinlingstuyl commented 5 months ago

Other comments before I open it up @pnp/cli-for-microsoft-365-maintainers ?

Jwaegebaert commented 5 months ago

I've no further comments, let's open this up.

MartinM85 commented 5 months ago

Can I work on it?

milanholemans commented 5 months ago

Can I work on it?

Sure, all yours!

MartinM85 commented 5 months ago

Just a tiny note. The subcommand add can be confusing for some users because with this command we allow

based on the action option.

Let's say, you want to remove an active assignment

m365 entra pim roleassignment request add --action adminRemove --roleDefinitionName 'SharePoint Administrator' --principalId 61b0c52f-a902-4769-9a09-c6628335b00a 

Also the description Request activation of an Entra ID role assignment for a user or group. is too generic. Users will need to check options properly to be clear what can be done with this command.

I know that the Graph API has one endpoint for this, but it supports multiple things

Does it make sense for you to have multiple commands instead of one m365 entra pim roleassignment request add?

There a risk that it will be hard for us to maintain the command and difficult to review any changes.

martinlingstuyl commented 5 months ago

Hi @MartinM85, you're making a good point. Maybe I should have thought a bit better on the user side of this. In other places we try to do the same: not mimic the api, but try to see what commands would benefit the user.

I think maybe we should spec this differently... what would you say? (I'm not sure how far along you are currently and how easy it is to adapt this to just do one thing.

MartinM85 commented 5 months ago

Hi @martinlingstuyl, it should be easy to adapt changes. It's working but hard to use, because it's not clear which options are required for which action. I haven't tested all possible combinations yet. Example:

martinlingstuyl commented 5 months ago

Ok, great @MartinM85, I'll create some new specs for this asap! I suggest we use this command to only assign yourself or someone else a role. (so adminAssign + selfActivate). Let's think on it a bit more. If you have suggestions I'm open to it.

MartinM85 commented 5 months ago

@martinlingstuyl Maybe instead of principalId => userId, userName, groupId, groupName ? Related to directoryScopeId, allowed values are

If a role has scope to an administrative unit, it would be useful specify an administrative unit by name. Same for scope to an app...appObjectId, appId or appName. Or we can keep directoryScopeId and add note what are allowed values

martinlingstuyl commented 5 months ago

Good ideas...

I'll incorporate those in my specs. I'm thinking of changing the planned commands a bit... how about the following?

m365 entra pim roleassignment list [options] - keep as planned m365 entra pim roleassignment eligibleroles list [options] - keep as planned, list eligible roles. m365 entra pim roleassignment requestedroles list [options] - To list pending requests m365 entra pim roleassignment add [options] - For adminAssign and selfActivate (so without 'request') m365 entra pim roleassignment remove [options] - For adminRemove and selfDeactivate

And maybe later use the following for some other scopes (Maybe for adminUpdate and/or the Renew and extend scopes) m365 entra pim roleassignment set [options]

Removing request is on purpose, it seems to me a better fit with the Azure Portal, and more user focussed, clearer in communicating intent.

martinlingstuyl commented 5 months ago

What do you think about the new specs @MartinM85, @pnp/cli-for-microsoft-365-maintainers?

@MartinM85, I've kept directoryScopeId and appScopeId out because I wasn't sure how you meant it. Could you explain a bit based on your research how these properties should work?

martinlingstuyl commented 5 months ago

I'm not sure though, may let's think on it some more...

MartinM85 commented 5 months ago

@martinlingstuyl I would keep directoryScopeId and appScopeId. I will add remark to the doc how to use these options. Current spec looks great.

MartinM85 commented 5 months ago

@martinlingstuyl Checking the spec, both duration and directoryScopeId has the same short option -d. Action option is missing

martinlingstuyl commented 5 months ago

We don't need action, as we're deciding between adminAssign and selfActivate, based on the options given.

I removed one -d short.

What do you think: should we add other expiration options, aside from duration?

MartinM85 commented 5 months ago

Ok, I was confused by 4th example where action option is still present.

The endpoint support endDateTime, so the user can specify either endDateTime or duration

martinlingstuyl commented 5 months ago

Ok, good point. I've removed the action option there.

I've also added an endDateTime option, as an optionset together with duration.

MartinM85 commented 5 months ago

Hi @martinlingstuyl, probably last update in spec. According to this conversation, we can get rid of appScopeId which is only allowed for entitlement management provider. In our case, we are working with directory (Entra ID) provider for role assignments and it supports only directoryScopeId.

martinlingstuyl commented 5 months ago

Awesome! Great research @MartinM85! I'll remove the option..

MartinM85 commented 5 months ago

@martinlingstuyl Based on https://github.com/pnp/cli-microsoft365/issues/5669#issuecomment-1941141838, should I rename the command and separate role and assignment?

m365 entra pim role assignment add [options]

martinlingstuyl commented 5 months ago

Hi @MartinM85, Let's see if one of the maintainers will give a second opinion first.

martinlingstuyl commented 4 months ago

Ok @MartinM85, you can update the naming and update the PR