This commit is contained in:
Goutham Muguluvalli Niranjan 2024-10-23 14:29:23 -05:00
Родитель 79d1254c0d
Коммит 593c6498bb
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 9B445AC83086D46E
2 изменённых файлов: 56 добавлений и 46 удалений

Просмотреть файл

@ -14,6 +14,7 @@ import (
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
mgmtnetwork "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2020-08-01/network"
"github.com/Azure/checkaccess-v2-go-sdk/client"
"github.com/Azure/go-autorest/autorest"
"github.com/Azure/go-autorest/autorest/azure"
"github.com/apparentlymart/go-cidr/cidr"
@ -24,7 +25,6 @@ import (
apisubnet "github.com/Azure/ARO-RP/pkg/api/util/subnet"
"github.com/Azure/ARO-RP/pkg/env"
"github.com/Azure/ARO-RP/pkg/util/azureclient"
"github.com/Azure/ARO-RP/pkg/util/azureclient/authz/remotepdp"
"github.com/Azure/ARO-RP/pkg/util/azureclient/azuresdk/armauthorization"
"github.com/Azure/ARO-RP/pkg/util/azureclient/mgmt/compute"
"github.com/Azure/ARO-RP/pkg/util/azureclient/mgmt/network"
@ -98,7 +98,7 @@ type dynamic struct {
resourceSkusClient compute.ResourceSkusClient
spNetworkUsage network.UsageClient
loadBalancerBackendAddressPoolsClient network.LoadBalancerBackendAddressPoolsClient
pdpClient remotepdp.RemotePDPClient
pdpClient client.RemotePDPClient
}
type AuthorizerType string
@ -118,7 +118,7 @@ func NewValidator(
appID *string,
authorizerType AuthorizerType,
cred azcore.TokenCredential,
pdpClient remotepdp.RemotePDPClient,
pdpClient client.RemotePDPClient,
) Dynamic {
return &dynamic{
log: log,
@ -435,41 +435,61 @@ func (dv *dynamic) validateActionsByOID(ctx context.Context, r *azure.Resource,
defer cancel()
c := closure{dv: dv, ctx: ctx, resource: r, actions: actions, oid: oid}
if err := c.checkAccessAuthReqPayloadData(); err != nil {
return err
}
return wait.PollImmediateUntil(30*time.Second, c.usingCheckAccessV2, timeoutCtx.Done())
}
// closure is the closure used in PollImmediateUntil's ConditionalFunc
type closure struct {
dv *dynamic
ctx context.Context
resource *azure.Resource
actions []string
oid *string
dv *dynamic
ctx context.Context
resource *azure.Resource
actions []string
oid *string
subjectAttributes client.SubjectAttributes
}
func (c *closure) checkAccessAuthReqPayloadData() error {
c.dv.log.Info("Prepare payload for CheckAccessV2 AuthZ")
scope := c.dv.azEnv.ResourceManagerEndpoint + "/.default"
t, err := c.dv.checkAccessSubjectInfoCred.GetToken(c.ctx, policy.TokenRequestOptions{Scopes: []string{scope}})
if err != nil {
c.dv.log.Error("Unable to get the token from AAD: ", err)
return err
}
tokenClaims, err := token.ExtractClaims(t.Token)
if err != nil {
c.dv.log.Error("Unable to parse the token oid claim: ", err)
return err
}
c.subjectAttributes.ObjectId = tokenClaims.ObjectId
if tokenClaims.ClaimNames != nil && len(tokenClaims.Groups) == 0 {
c.subjectAttributes.ClaimName = client.GroupExpansion
} else if tokenClaims.ClaimNames == nil && len(tokenClaims.Groups) > 0 {
c.subjectAttributes.Groups = tokenClaims.Groups
}
return nil
}
// usingCheckAccessV2 uses the new RBAC checkAccessV2 API
func (c closure) usingCheckAccessV2() (bool, error) {
c.dv.log.Info("validateActions with CheckAccessV2")
// reusing oid during retries
if c.oid == nil {
scope := c.dv.azEnv.ResourceManagerEndpoint + "/.default"
t, err := c.dv.checkAccessSubjectInfoCred.GetToken(c.ctx, policy.TokenRequestOptions{Scopes: []string{scope}})
if err != nil {
c.dv.log.Error("Unable to get the token from AAD: ", err)
// reusing oid and groups/claimNames during retries
if c.subjectAttributes.ObjectId == "" ||
(c.subjectAttributes.ClaimName == "" && len(c.subjectAttributes.Groups) == 0) {
if err := c.checkAccessAuthReqPayloadData(); err != nil {
return false, err
}
oid, err := token.GetObjectId(t.Token)
if err != nil {
c.dv.log.Error("Unable to parse the token oid claim: ", err)
return false, err
}
c.oid = &oid
}
authReq := createAuthorizationRequest(*c.oid, c.resource.String(), c.actions...)
authReq := c.dv.pdpClient.CreateAuthorizationRequest(c.resource.String(), c.actions, c.subjectAttributes)
results, err := c.dv.pdpClient.CheckAccess(c.ctx, authReq)
if err != nil {
c.dv.log.Error("Unexpected error when calling CheckAccessV2: ", err)
@ -489,39 +509,19 @@ func (c closure) usingCheckAccessV2() (bool, error) {
_, ok := actionsToFind[result.ActionId]
if ok {
delete(actionsToFind, result.ActionId)
if result.AccessDecision != remotepdp.Allowed {
if result.AccessDecision != client.Allowed {
return false, nil
}
}
}
if len(actionsToFind) > 0 {
c.dv.log.Infof("The result didn't include permissions %v for object ID: %s", actionsToFind, *c.oid)
c.dv.log.Infof("The result didn't include permissions %v for object ID: %s", actionsToFind, c.subjectAttributes.ObjectId)
return false, nil
}
return true, nil
}
func createAuthorizationRequest(subject, resourceId string, actions ...string) remotepdp.AuthorizationRequest {
actionInfos := []remotepdp.ActionInfo{}
for _, action := range actions {
actionInfos = append(actionInfos, remotepdp.ActionInfo{Id: action})
}
return remotepdp.AuthorizationRequest{
Subject: remotepdp.SubjectInfo{
Attributes: remotepdp.SubjectAttributes{
ObjectId: subject,
ClaimName: remotepdp.GroupExpansion, // always do group expansion
},
},
Actions: actionInfos,
Resource: remotepdp.ResourceInfo{
Id: resourceId,
},
}
}
func (dv *dynamic) validateCIDRRanges(ctx context.Context, subnets []Subnet, additionalCIDRs ...string) error {
dv.log.Print("ValidateCIDRRanges")

Просмотреть файл

@ -11,6 +11,7 @@ import (
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/checkaccess-v2-go-sdk/client"
"github.com/Azure/go-autorest/autorest"
"github.com/Azure/go-autorest/autorest/to"
"github.com/form3tech-oss/jwt-go"
@ -18,7 +19,7 @@ import (
"github.com/Azure/ARO-RP/pkg/api"
"github.com/Azure/ARO-RP/pkg/env"
"github.com/Azure/ARO-RP/pkg/util/azureclient/authz/remotepdp"
"github.com/Azure/ARO-RP/pkg/util/azureclient"
"github.com/Azure/ARO-RP/pkg/util/azureclient/azuresdk/armauthorization"
"github.com/Azure/ARO-RP/pkg/util/platformworkloadidentity"
"github.com/Azure/ARO-RP/pkg/validate/dynamic"
@ -127,11 +128,20 @@ func (dv *openShiftClusterDynamicValidator) Dynamic(ctx context.Context) error {
}
aroEnv := dv.env.Environment()
pdpClient := remotepdp.NewRemotePDPClient(
clientOptions := &azcore.ClientOptions{
Transport: &http.Client{
Transport: azureclient.NewCustomRoundTripper(http.DefaultTransport),
},
}
pdpClient, err := client.NewRemotePDPClient(
fmt.Sprintf(aroEnv.Endpoint, dv.env.Location()),
aroEnv.OAuthScope,
fpClientCred,
clientOptions,
)
if err != nil {
return err
}
scopes := []string{dv.env.Environment().ResourceManagerScope}
var spDynamic dynamic.Dynamic