Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Always do group expansion for CheckAccess subjects #3710

Merged
merged 1 commit into from
Jul 23, 2024

Conversation

nwnt
Copy link
Contributor

@nwnt nwnt commented Jul 20, 2024

Which issue this PR addresses:

Fixes: ARO-9261

What this PR does / why we need it:

Refer to the IcM in JIRA, CheckAccess team informed that we need to send an additional field to give hints to CheckAccess that "group expansion" is needed.

Without group expansion, CheckAccess will not take into account what groups the principal belongs to. That is, if a service principal A is a member of group B, and group B allows writing to a VNet, calling CheckAccess without the group expansion field will return a response that A is not allowed to write to a VNet. With the group expansion hint, CheckAccess will return an allowed response, which is the behavior we want.

Test plan for issue:

I reproduced this by creating a Deny Assignment on a VNet resource from Azure Blueprint and made a group excluded from it. The testing app principal is then added to the group. After that I verified the following 2 scenarios:

  1. Without group expansion, CheckAccess will return some actions as denied. Here are the request, the response and the formatted response:
    Request (notice the lack of the new _Claim_Name field in Subject)
{
    "Subject": {
        "Attributes": {
            "ObjectId": "69f8005a-36fe-4aa7-b161-c435d34133ad"
        }
    },
    "Actions": [
        {
            "Id": "Microsoft.ClassicNetwork/networkSecurityGroups/securityRules/write",
            "Attributes": null
        },
        {
            "Id": "Microsoft.Network/virtualNetworks/join/action",
            "Attributes": {}
        },
        {
            "Id": "Microsoft.Network/virtualNetworks/read",
            "Attributes": {}
        },
        {
            "Id": "Microsoft.Network/virtualNetworks/write",
            "Attributes": {}
        },
        {
            "Id": "Microsoft.Network/virtualNetworks/subnets/join/action",
            "Attributes": {}
        },
        {
            "Id": "Microsoft.Network/virtualNetworks/subnets/read",
            "Attributes": {}
        },
        {
            "Id": "Microsoft.Network/virtualNetworks/subnets/write",
            "Attributes": {}
        }
    ],
    "Resource": {
        "Id": "/subscriptions/60bf318d-6914-4105-a3b5-d0d2c10388c8/resourceGroups/nont-test-assignment/providers/Microsoft.Network/virtualNetworks/net-wgssmdvlnix4m",
        "Attributes": {}
    },
    "Environment": {
        "Attributes": null
    }
}

Response (Notice that some actions were reported as denied)

{
    "value": [
        {
            "accessDecision": "Denied",
            "actionId": "Microsoft.ClassicNetwork/networkSecurityGroups/securityRules/write",
            "isDataAction": false,
            "roleAssignment": null,
            "denyAssignment": {
                "isSystemProtected": true,
                "id": "d778a6b1157f2abbbe280825f36196f1",
                "name": "",
                "description": "",
                "permissions": [
                    {
                        "actions": [
                            "*"
                        ],
                        "notActions": [
                            "Microsoft.Authorization/locks/delete",
                            "*/read",
                            "Microsoft.Network/virtualNetworks/subnets/join/action"
                        ],
                        "dataActions": [],
                        "notDataActions": [],
                        "condition": "",
                        "conditionVersion": ""
                    }
                ],
                "scope": "/subscriptions/60bf318d-6914-4105-a3b5-d0d2c10388c8/resourceGroups/nont-test-assignment/providers/Microsoft.Network/virtualNetworks/net-wgssmdvlnix4m",
                "doNotApplyToChildScopes": false,
                "principals": [
                    {
                        "id": "00000000000000000000000000000000",
                        "type": "SystemDefined"
                    }
                ],
                "excludePrincipals": [
                    {
                        "id": "864512b599134a29b4c9ea8d1117f181",
                        "type": "ServicePrincipal"
                    },
                    {
                        "id": "1cae329ebf0b4456b8d4d74b1c5e7077",
                        "type": "Group"
                    }
                ],
                "condition": "",
                "conditionVersion": "",
                "effect": null
            },
            "timeToLiveInMs": 60000
        },
        {
            "accessDecision": "Denied",
            "actionId": "Microsoft.Network/virtualNetworks/join/action",
            "isDataAction": false,
            "roleAssignment": null,
            "denyAssignment": {
                "isSystemProtected": true,
                "id": "d778a6b1157f2abbbe280825f36196f1",
                "name": "",
                "description": "",
                "permissions": [
                    {
                        "actions": [
                            "*"
                        ],
                        "notActions": [
                            "Microsoft.Authorization/locks/delete",
                            "*/read",
                            "Microsoft.Network/virtualNetworks/subnets/join/action"
                        ],
                        "dataActions": [],
                        "notDataActions": [],
                        "condition": "",
                        "conditionVersion": ""
                    }
                ],
                "scope": "/subscriptions/60bf318d-6914-4105-a3b5-d0d2c10388c8/resourceGroups/nont-test-assignment/providers/Microsoft.Network/virtualNetworks/net-wgssmdvlnix4m",
                "doNotApplyToChildScopes": false,
                "principals": [
                    {
                        "id": "00000000000000000000000000000000",
                        "type": "SystemDefined"
                    }
                ],
                "excludePrincipals": [
                    {
                        "id": "864512b599134a29b4c9ea8d1117f181",
                        "type": "ServicePrincipal"
                    },
                    {
                        "id": "1cae329ebf0b4456b8d4d74b1c5e7077",
                        "type": "Group"
                    }
                ],
                "condition": "",
                "conditionVersion": "",
                "effect": null
            },
            "timeToLiveInMs": 60000
        },
        {
            "accessDecision": "Allowed",
            "actionId": "Microsoft.Network/virtualNetworks/read",
            "isDataAction": false,
            "roleAssignment": {
                "delegatedManagedIdentityResourceId": "",
                "id": "f7268f5c440747728341363f5446d35f",
                "roleDefinitionId": "b24988ac618042a0ab8820f7382dd24c",
                "principalId": "69f8005a36fe4aa7b161c435d34133ad",
                "principalType": "ServicePrincipal",
                "scope": "/subscriptions/60bf318d-6914-4105-a3b5-d0d2c10388c8",
                "condition": "",
                "conditionVersion": "",
                "canDelegate": false,
                "description": ""
            },
            "denyAssignment": null,
            "timeToLiveInMs": 60000
        },
        {
            "accessDecision": "Denied",
            "actionId": "Microsoft.Network/virtualNetworks/write",
            "isDataAction": false,
            "roleAssignment": null,
            "denyAssignment": {
                "isSystemProtected": true,
                "id": "d778a6b1157f2abbbe280825f36196f1",
                "name": "",
                "description": "",
                "permissions": [
                    {
                        "actions": [
                            "*"
                        ],
                        "notActions": [
                            "Microsoft.Authorization/locks/delete",
                            "*/read",
                            "Microsoft.Network/virtualNetworks/subnets/join/action"
                        ],
                        "dataActions": [],
                        "notDataActions": [],
                        "condition": "",
                        "conditionVersion": ""
                    }
                ],
                "scope": "/subscriptions/60bf318d-6914-4105-a3b5-d0d2c10388c8/resourceGroups/nont-test-assignment/providers/Microsoft.Network/virtualNetworks/net-wgssmdvlnix4m",
                "doNotApplyToChildScopes": false,
                "principals": [
                    {
                        "id": "00000000000000000000000000000000",
                        "type": "SystemDefined"
                    }
                ],
                "excludePrincipals": [
                    {
                        "id": "864512b599134a29b4c9ea8d1117f181",
                        "type": "ServicePrincipal"
                    },
                    {
                        "id": "1cae329ebf0b4456b8d4d74b1c5e7077",
                        "type": "Group"
                    }
                ],
                "condition": "",
                "conditionVersion": "",
                "effect": null
            },
            "timeToLiveInMs": 60000
        },
        {
            "accessDecision": "Allowed",
            "actionId": "Microsoft.Network/virtualNetworks/subnets/join/action",
            "isDataAction": false,
            "roleAssignment": {
                "delegatedManagedIdentityResourceId": "",
                "id": "f7268f5c440747728341363f5446d35f",
                "roleDefinitionId": "b24988ac618042a0ab8820f7382dd24c",
                "principalId": "69f8005a36fe4aa7b161c435d34133ad",
                "principalType": "ServicePrincipal",
                "scope": "/subscriptions/60bf318d-6914-4105-a3b5-d0d2c10388c8",
                "condition": "",
                "conditionVersion": "",
                "canDelegate": false,
                "description": ""
            },
            "denyAssignment": null,
            "timeToLiveInMs": 60000
        },
        {
            "accessDecision": "Allowed",
            "actionId": "Microsoft.Network/virtualNetworks/subnets/read",
            "isDataAction": false,
            "roleAssignment": {
                "delegatedManagedIdentityResourceId": "",
                "id": "f7268f5c440747728341363f5446d35f",
                "roleDefinitionId": "b24988ac618042a0ab8820f7382dd24c",
                "principalId": "69f8005a36fe4aa7b161c435d34133ad",
                "principalType": "ServicePrincipal",
                "scope": "/subscriptions/60bf318d-6914-4105-a3b5-d0d2c10388c8",
                "condition": "",
                "conditionVersion": "",
                "canDelegate": false,
                "description": ""
            },
            "denyAssignment": null,
            "timeToLiveInMs": 60000
        },
        {
            "accessDecision": "Denied",
            "actionId": "Microsoft.Network/virtualNetworks/subnets/write",
            "isDataAction": false,
            "roleAssignment": null,
            "denyAssignment": {
                "isSystemProtected": true,
                "id": "d778a6b1157f2abbbe280825f36196f1",
                "name": "",
                "description": "",
                "permissions": [
                    {
                        "actions": [
                            "*"
                        ],
                        "notActions": [
                            "Microsoft.Authorization/locks/delete",
                            "*/read",
                            "Microsoft.Network/virtualNetworks/subnets/join/action"
                        ],
                        "dataActions": [],
                        "notDataActions": [],
                        "condition": "",
                        "conditionVersion": ""
                    }
                ],
                "scope": "/subscriptions/60bf318d-6914-4105-a3b5-d0d2c10388c8/resourceGroups/nont-test-assignment/providers/Microsoft.Network/virtualNetworks/net-wgssmdvlnix4m",
                "doNotApplyToChildScopes": false,
                "principals": [
                    {
                        "id": "00000000000000000000000000000000",
                        "type": "SystemDefined"
                    }
                ],
                "excludePrincipals": [
                    {
                        "id": "864512b599134a29b4c9ea8d1117f181",
                        "type": "ServicePrincipal"
                    },
                    {
                        "id": "1cae329ebf0b4456b8d4d74b1c5e7077",
                        "type": "Group"
                    }
                ],
                "condition": "",
                "conditionVersion": "",
                "effect": null
            },
            "timeToLiveInMs": 60000
        }
    ],
    "nextLink": null
}
  1. With group expansion hint
    Request (Notice the additional field in Subject)
{
    "Subject": {
        "Attributes": {
            "ObjectId": "69f8005a-36fe-4aa7-b161-c435d34133ad",
            "_claim_names": "{\"groups\":\"ENGORGIO~!\"}"
        }
    },
    "Actions": [
        {
            "Id": "Microsoft.ClassicNetwork/networkSecurityGroups/securityRules/write",
            "Attributes": null
        },
        {
            "Id": "Microsoft.Network/virtualNetworks/join/action",
            "Attributes": {}
        },
        {
            "Id": "Microsoft.Network/virtualNetworks/read",
            "Attributes": {}
        },
        {
            "Id": "Microsoft.Network/virtualNetworks/write",
            "Attributes": {}
        },
        {
            "Id": "Microsoft.Network/virtualNetworks/subnets/join/action",
            "Attributes": {}
        },
        {
            "Id": "Microsoft.Network/virtualNetworks/subnets/read",
            "Attributes": {}
        },
        {
            "Id": "Microsoft.Network/virtualNetworks/subnets/write",
            "Attributes": {}
        }
    ],
    "Resource": {
        "Id": "/subscriptions/60bf318d-6914-4105-a3b5-d0d2c10388c8/resourceGroups/nont-test-assignment/providers/Microsoft.Network/virtualNetworks/net-wgssmdvlnix4m",
        "Attributes": {}
    },
    "Environment": {
        "Attributes": null
    }
}

Response (all actions are allowed)

{
    "value": [
        {
            "accessDecision": "Allowed",
            "actionId": "Microsoft.ClassicNetwork/networkSecurityGroups/securityRules/write",
            "isDataAction": false,
            "roleAssignment": {
                "delegatedManagedIdentityResourceId": "",
                "id": "f7268f5c440747728341363f5446d35f",
                "roleDefinitionId": "b24988ac618042a0ab8820f7382dd24c",
                "principalId": "69f8005a36fe4aa7b161c435d34133ad",
                "principalType": "ServicePrincipal",
                "scope": "/subscriptions/60bf318d-6914-4105-a3b5-d0d2c10388c8",
                "condition": "",
                "conditionVersion": "",
                "canDelegate": false,
                "description": ""
            },
            "denyAssignment": null,
            "timeToLiveInMs": 60000
        },
        {
            "accessDecision": "Allowed",
            "actionId": "Microsoft.Network/virtualNetworks/join/action",
            "isDataAction": false,
            "roleAssignment": {
                "delegatedManagedIdentityResourceId": "",
                "id": "f7268f5c440747728341363f5446d35f",
                "roleDefinitionId": "b24988ac618042a0ab8820f7382dd24c",
                "principalId": "69f8005a36fe4aa7b161c435d34133ad",
                "principalType": "ServicePrincipal",
                "scope": "/subscriptions/60bf318d-6914-4105-a3b5-d0d2c10388c8",
                "condition": "",
                "conditionVersion": "",
                "canDelegate": false,
                "description": ""
            },
            "denyAssignment": null,
            "timeToLiveInMs": 60000
        },
        {
            "accessDecision": "Allowed",
            "actionId": "Microsoft.Network/virtualNetworks/read",
            "isDataAction": false,
            "roleAssignment": {
                "delegatedManagedIdentityResourceId": "",
                "id": "f7268f5c440747728341363f5446d35f",
                "roleDefinitionId": "b24988ac618042a0ab8820f7382dd24c",
                "principalId": "69f8005a36fe4aa7b161c435d34133ad",
                "principalType": "ServicePrincipal",
                "scope": "/subscriptions/60bf318d-6914-4105-a3b5-d0d2c10388c8",
                "condition": "",
                "conditionVersion": "",
                "canDelegate": false,
                "description": ""
            },
            "denyAssignment": null,
            "timeToLiveInMs": 60000
        },
        {
            "accessDecision": "Allowed",
            "actionId": "Microsoft.Network/virtualNetworks/write",
            "isDataAction": false,
            "roleAssignment": {
                "delegatedManagedIdentityResourceId": "",
                "id": "f7268f5c440747728341363f5446d35f",
                "roleDefinitionId": "b24988ac618042a0ab8820f7382dd24c",
                "principalId": "69f8005a36fe4aa7b161c435d34133ad",
                "principalType": "ServicePrincipal",
                "scope": "/subscriptions/60bf318d-6914-4105-a3b5-d0d2c10388c8",
                "condition": "",
                "conditionVersion": "",
                "canDelegate": false,
                "description": ""
            },
            "denyAssignment": null,
            "timeToLiveInMs": 60000
        },
        {
            "accessDecision": "Allowed",
            "actionId": "Microsoft.Network/virtualNetworks/subnets/join/action",
            "isDataAction": false,
            "roleAssignment": {
                "delegatedManagedIdentityResourceId": "",
                "id": "f7268f5c440747728341363f5446d35f",
                "roleDefinitionId": "b24988ac618042a0ab8820f7382dd24c",
                "principalId": "69f8005a36fe4aa7b161c435d34133ad",
                "principalType": "ServicePrincipal",
                "scope": "/subscriptions/60bf318d-6914-4105-a3b5-d0d2c10388c8",
                "condition": "",
                "conditionVersion": "",
                "canDelegate": false,
                "description": ""
            },
            "denyAssignment": null,
            "timeToLiveInMs": 60000
        },
        {
            "accessDecision": "Allowed",
            "actionId": "Microsoft.Network/virtualNetworks/subnets/read",
            "isDataAction": false,
            "roleAssignment": {
                "delegatedManagedIdentityResourceId": "",
                "id": "f7268f5c440747728341363f5446d35f",
                "roleDefinitionId": "b24988ac618042a0ab8820f7382dd24c",
                "principalId": "69f8005a36fe4aa7b161c435d34133ad",
                "principalType": "ServicePrincipal",
                "scope": "/subscriptions/60bf318d-6914-4105-a3b5-d0d2c10388c8",
                "condition": "",
                "conditionVersion": "",
                "canDelegate": false,
                "description": ""
            },
            "denyAssignment": null,
            "timeToLiveInMs": 60000
        },
        {
            "accessDecision": "Allowed",
            "actionId": "Microsoft.Network/virtualNetworks/subnets/write",
            "isDataAction": false,
            "roleAssignment": {
                "delegatedManagedIdentityResourceId": "",
                "id": "f7268f5c440747728341363f5446d35f",
                "roleDefinitionId": "b24988ac618042a0ab8820f7382dd24c",
                "principalId": "69f8005a36fe4aa7b161c435d34133ad",
                "principalType": "ServicePrincipal",
                "scope": "/subscriptions/60bf318d-6914-4105-a3b5-d0d2c10388c8",
                "condition": "",
                "conditionVersion": "",
                "canDelegate": false,
                "description": ""
            },
            "denyAssignment": null,
            "timeToLiveInMs": 60000
        }
    ],
    "nextLink": null
}

Is there any documentation that needs to be updated for this PR?

N/A - the code should be clear enough.

How do you know this will function as expected in production?

E2E tests should be enough.

@nwnt
Copy link
Contributor Author

nwnt commented Jul 20, 2024

/azp run e2e,ci

Copy link

Azure Pipelines successfully started running 2 pipeline(s).

@nwnt nwnt added ready-for-review next-up next-release To be included in the next RP release rollout labels Jul 20, 2024
@nwnt
Copy link
Contributor Author

nwnt commented Jul 20, 2024

/azp run ci

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

mociarain
mociarain previously approved these changes Jul 22, 2024
Copy link
Collaborator

@mociarain mociarain left a comment

Choose a reason for hiding this comment

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

I agree with Weinongs comments but LGTM after that. I've re-run the E2E tests to see if that failure was just a flake. I had a look through the test that failed and it's not obvious to me that this change was related so 🤞

Copy link
Collaborator

@SrinivasAtmakuri SrinivasAtmakuri left a comment

Choose a reason for hiding this comment

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

LGTM!

Copy link
Collaborator

@anshulvermapatel anshulvermapatel left a comment

Choose a reason for hiding this comment

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

I too agree with Weinong. Once thats done, LGTM

Copy link

@AldoFusterTurpin AldoFusterTurpin left a comment

Choose a reason for hiding this comment

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

Not a blocker but a small suggestion. LGTM

pkg/util/azureclient/authz/remotepdp/types.go Outdated Show resolved Hide resolved
Copy link
Contributor

@weinong weinong left a comment

Choose a reason for hiding this comment

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

will approve once the magic word is updated.

@nwnt nwnt dismissed stale reviews from SrinivasAtmakuri and mociarain via e20b612 July 22, 2024 16:09
@nwnt nwnt force-pushed the nwnt/add-checkaccess-group-expansion branch from 96f6be1 to e20b612 Compare July 22, 2024 16:09
@nwnt
Copy link
Contributor Author

nwnt commented Jul 22, 2024

/azp run ci,e2e

Copy link

Azure Pipelines successfully started running 2 pipeline(s).

Copy link
Contributor

@weinong weinong left a comment

Choose a reason for hiding this comment

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

LGTM

Comment on lines +20 to +26

// GroupExpansion is the value to be used with ClaimName in SubjectAttributes
// This value gives CheckAccess a hint that it needs to retrieve all the groups the principal belongs to
// and then give the response based on all group entitlements.
//
// https://eng.ms/docs/microsoft-security/identity/auth/access-control-managed-identityacmi/azure-authz-data-plane/authz-dataplane-partner-wiki/remotepdp/checkaccess/samples/requestresponse
GroupExpansion = `{"groups":"src1"}`

Choose a reason for hiding this comment

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

@nwnt Also, thanks a lot for the pointers to the docs as sometimes that kind of info is not easy to find. 🙂

Copy link

@AldoFusterTurpin AldoFusterTurpin left a comment

Choose a reason for hiding this comment

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

LGTM. Thanks. Just one remaining question from my side.

pkg/util/azureclient/authz/remotepdp/types.go Show resolved Hide resolved
@mociarain mociarain merged commit 18fa5ec into master Jul 23, 2024
21 checks passed
@mociarain mociarain deleted the nwnt/add-checkaccess-group-expansion branch July 23, 2024 06:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
next-release To be included in the next RP release rollout next-up ready-for-review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants