Skip to content

Commit

Permalink
Initial command to create the managed identity and role
Browse files Browse the repository at this point in the history
  • Loading branch information
mvbrock committed Oct 13, 2024
1 parent 4d3f741 commit 979537d
Show file tree
Hide file tree
Showing 8 changed files with 144 additions and 5 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ require (
connectrpc.com/connect v1.17.0
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization v1.0.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v3 v3.0.1
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v2 v2.4.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi v1.2.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,8 @@ github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0/go.mod h1:eWRD7oawr1Mu1sLC
github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.1/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization v1.0.0 h1:qtRcg5Y7jNJ4jEzPq4GpWLfTspHdNe2ZK6LjwGcjgmU=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization v1.0.0/go.mod h1:lPneRe3TwsoDRKY4O6YDLXHhEWrD+TIRa8XrV/3/fqw=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v3 v3.0.1 h1:H3g2mkmu105ON0c/Gqx3Bm+bzoIijLom8LmV9Gjn7X0=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v3 v3.0.1/go.mod h1:EAc3kjhZf9soch7yLID8PeKcE6VfKvQTllSBHYVdXd8=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v2 v2.4.0 h1:1u/K2BFv0MwkG6he8RYuUcbbeK22rkoZbg4lKa/msZU=
Expand Down
15 changes: 15 additions & 0 deletions lib/config/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,8 @@ type CommandLineFlags struct {
// `teleport integration configure access-graph aws-iam` command
IntegrationConfAccessGraphAWSSyncArguments IntegrationConfAccessGraphAWSSync

IntegrationConfAccessGraphAzureSyncArguments IntegrationConfAccessGraphAzureSync

// IntegrationConfAzureOIDCArguments contains the arguments of
// `teleport integration configure azure-oidc` command
IntegrationConfAzureOIDCArguments IntegrationConfAzureOIDC
Expand Down Expand Up @@ -283,6 +285,19 @@ type IntegrationConfAccessGraphAWSSync struct {
AutoConfirm bool
}

// IntegrationConfAccessGraphAzureSync contains the arguments of
// `teleport integration configure access-graph azure` command.
type IntegrationConfAccessGraphAzureSync struct {
// ManagedIdentity is the principal performing the discovery
ManagedIdentity string
// Role is the Azure Role associated with the integration
Role string
// SubscriptionID is the Azure subscription containing resources for sync
SubscriptionID string
// AutoConfirm skips user confirmation of the operation plan if true.
AutoConfirm bool
}

// IntegrationConfAzureOIDC contains the arguments of
// `teleport integration configure azure-oidc` command
type IntegrationConfAzureOIDC struct {
Expand Down
107 changes: 107 additions & 0 deletions lib/integrations/azureoidc/accessgraph_sync.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package azureoidc

import (
"context"
"fmt"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi"
"github.com/google/uuid"
"github.com/gravitational/teleport/lib/cloud/provisioning"
"github.com/gravitational/teleport/lib/config"
"github.com/gravitational/trace"
"log/slog"
"os"
)

func newManagedIdAction(cred *azidentity.DefaultAzureCredential, subId string, name string) (*provisioning.Action, error) {
runnerFn := func(ctx context.Context) error {
// Create the managed identity
userIdCli, err := armmsi.NewUserAssignedIdentitiesClient(subId, cred, nil)
if err != nil {
return trace.Wrap(fmt.Errorf("could not create managed identity client: %v", err))
}
id := armmsi.Identity{}
mgdIdRes, err := userIdCli.CreateOrUpdate(ctx, "", name, id, nil)
if err != nil {
return trace.Wrap(fmt.Errorf("could not create managed identity: %v", err))
}
slog.InfoContext(ctx, fmt.Sprintf(
"Managed identity created, Name: %s, ID: %s", *mgdIdRes.Name, *mgdIdRes.ID))

// Create the role
roleDefCli, err := armauthorization.NewRoleDefinitionsClient(cred, nil)
if err != nil {
return trace.Wrap(fmt.Errorf("failed to create role definitions client: %v", err))
}
roleDefId := uuid.New().String()
customRole := "CustomRole"
// TODO(mbrock): Determine scope
scope := ""
roleDefinition := armauthorization.RoleDefinition{
Name: &roleDefId,
Properties: &armauthorization.RoleDefinitionProperties{
RoleName: &name,
RoleType: &customRole,
Permissions: []*armauthorization.Permission{
// TODO(mbrock): Add permissions
},
AssignableScopes: []*string{&scope}, // Scope must be provided
},
}
roleRes, err := roleDefCli.CreateOrUpdate(ctx, scope, roleDefId, roleDefinition, nil)
if err != nil {
return trace.Wrap(fmt.Errorf("failed to create custom role: %v", err))
}

// Assign the role to the managed identity
roleAssignCli, err := armauthorization.NewRoleAssignmentsClient(subId, cred, nil)
if err != nil {
return fmt.Errorf("failed to create role assignments client: %v", err)
}
assignName := uuid.New().String()
if err != nil {
return trace.Wrap(fmt.Errorf("failed to create role assignments client: %v", err))
}
roleAssignParams := armauthorization.RoleAssignmentCreateParameters{
Properties: &armauthorization.RoleAssignmentProperties{
PrincipalID: mgdIdRes.ID,
RoleDefinitionID: roleRes.ID,
},
}
_, err = roleAssignCli.Create(ctx, scope, assignName, roleAssignParams, nil)
if err != nil {
return fmt.Errorf("failed to create role assignment: %v", err)
}

return nil
}
cfg := provisioning.ActionConfig{
Name: "NewSyncManagedId",
Summary: "Creates a new Azure managed ID for the discovery service to use",
RunnerFn: runnerFn,
}
return provisioning.NewAction(cfg)
}

// ConfigureAccessGraphSyncAzure sets up the managed identity and role required for Teleport to be able to pull
// AWS resources into Teleport.
func ConfigureAccessGraphSyncAzure(ctx context.Context, params config.IntegrationConfAccessGraphAzureSync) error {
cred, err := azidentity.NewDefaultAzureCredential(nil)
if err != nil {
return trace.Wrap(err)
}
managedIdAction, err := newManagedIdAction(cred, params.SubscriptionID, params.ManagedIdentity)
if err != nil {
return trace.Wrap(err)
}
opCfg := provisioning.OperationConfig{
Name: "access-graph-azure-sync",
Actions: []provisioning.Action{
*managedIdAction,
},
AutoConfirm: params.AutoConfirm,
Output: os.Stdout,
}
return trace.Wrap(provisioning.Run(ctx, opCfg))
}
6 changes: 6 additions & 0 deletions tool/teleport/common/integration_configure.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,12 @@ func onIntegrationConfAccessGraphAWSSync(ctx context.Context, params config.Inte
return trace.Wrap(awsoidc.ConfigureAccessGraphSyncIAM(ctx, clt, confReq))
}

func onIntegrationConfAccessGraphAzureSync(ctx context.Context, params config.IntegrationConfAccessGraphAzureSync) error {
// Ensure we print output to the user. LogLevel at this point was set to Error.
utils.InitLogger(utils.LoggingForDaemon, slog.LevelInfo)
return trace.Wrap(azureoidc.ConfigureAccessGraphSyncAzure(ctx, params))
}

func onIntegrationConfAzureOIDCCmd(ctx context.Context, params config.IntegrationConfAzureOIDC) error {
// Ensure we print output to the user. LogLevel at this point was set to Error.
utils.InitLogger(utils.LoggingForDaemon, slog.LevelInfo)
Expand Down
18 changes: 13 additions & 5 deletions tool/teleport/common/teleport.go
Original file line number Diff line number Diff line change
Expand Up @@ -507,10 +507,16 @@ func Run(options Options) (app *kingpin.Application, executedCommand string, con
integrationConfEKSCmd.Flag("confirm", "Apply changes without confirmation prompt.").BoolVar(&ccf.IntegrationConfEKSIAMArguments.AutoConfirm)

integrationConfAccessGraphCmd := integrationConfigureCmd.Command("access-graph", "Manages Access Graph configuration.")
integrationConfTAGSyncCmd := integrationConfAccessGraphCmd.Command("aws-iam", "Adds required IAM permissions for syncing data into Access Graph service.")
integrationConfTAGSyncCmd.Flag("role", "The AWS Role used by the AWS OIDC Integration.").Required().StringVar(&ccf.IntegrationConfAccessGraphAWSSyncArguments.Role)
integrationConfTAGSyncCmd.Flag("aws-account-id", "The AWS account ID.").StringVar(&ccf.IntegrationConfAccessGraphAWSSyncArguments.AccountID)
integrationConfTAGSyncCmd.Flag("confirm", "Apply changes without confirmation prompt.").BoolVar(&ccf.IntegrationConfAccessGraphAWSSyncArguments.AutoConfirm)
integrationConfAccessGraphAWSSyncCmd := integrationConfAccessGraphCmd.Command("aws-iam", "Adds required IAM permissions for syncing data into Access Graph service.")
integrationConfAccessGraphAWSSyncCmd.Flag("role", "The AWS Role used by the AWS OIDC Integration.").Required().StringVar(&ccf.IntegrationConfAccessGraphAWSSyncArguments.Role)
integrationConfAccessGraphAWSSyncCmd.Flag("aws-account-id", "The AWS account ID.").StringVar(&ccf.IntegrationConfAccessGraphAWSSyncArguments.AccountID)
integrationConfAccessGraphAWSSyncCmd.Flag("confirm", "Apply changes without confirmation prompt.").BoolVar(&ccf.IntegrationConfAccessGraphAWSSyncArguments.AutoConfirm)

integrationConfAccessGraphAzureSyncCmd := integrationConfAccessGraphCmd.Command("azure", "Creates/updates permissions for syncing data into Access Graph service.")
integrationConfAccessGraphAzureSyncCmd.Flag("managed-identity", "The managed identity runs the discovery service.").Required()
integrationConfAccessGraphAzureSyncCmd.Flag("role", "The role attached to the managed identity with the discovery permissions.").Required()
integrationConfAccessGraphAzureSyncCmd.Flag("subscription-id", "The subscription ID in which to discovery resources.")
integrationConfAccessGraphAzureSyncCmd.Flag("confirm", "Apply changes without confirmation prompt.")

integrationConfAWSOIDCIdPCmd := integrationConfigureCmd.Command("awsoidc-idp", "Creates an IAM IdP (OIDC) in your AWS account to allow the AWS OIDC Integration to access AWS APIs.")
integrationConfAWSOIDCIdPCmd.Flag("cluster", "Teleport Cluster name.").Required().StringVar(&ccf.
Expand Down Expand Up @@ -719,8 +725,10 @@ Examples:
err = onIntegrationConfListDatabasesIAM(ctx, ccf.IntegrationConfListDatabasesIAMArguments)
case integrationConfExternalAuditCmd.FullCommand():
err = onIntegrationConfExternalAuditCmd(ctx, ccf.IntegrationConfExternalAuditStorageArguments)
case integrationConfTAGSyncCmd.FullCommand():
case integrationConfAccessGraphAWSSyncCmd.FullCommand():
err = onIntegrationConfAccessGraphAWSSync(ctx, ccf.IntegrationConfAccessGraphAWSSyncArguments)
case integrationConfAccessGraphAzureSyncCmd.FullCommand():
err = onIntegrationConfAccessGraphAzureSync(ctx, ccf.IntegrationConfAccessGraphAzureSyncArguments)
case integrationConfAzureOIDCCmd.FullCommand():
err = onIntegrationConfAzureOIDCCmd(ctx, ccf.IntegrationConfAzureOIDCArguments)
case integrationSAMLIdPGCPWorkforce.FullCommand():
Expand Down

0 comments on commit 979537d

Please sign in to comment.