Skip to content

Implement credential validation in AWS provider#61

Closed
dcmcand wants to merge 1 commit into
mainfrom
feature/aws-credential-validation
Closed

Implement credential validation in AWS provider#61
dcmcand wants to merge 1 commit into
mainfrom
feature/aws-credential-validation

Conversation

@dcmcand

@dcmcand dcmcand commented Feb 5, 2026

Copy link
Copy Markdown
Contributor

Summary

Implements AWS credential validation as described in #6. This adds:

  • Default validation: Silent sts:GetCallerIdentity check on every nic validate command
  • Thorough validation: --validate-creds flag runs IAM Policy Simulator to verify all required permissions
  • Config-aware permissions: Skips VPC/IAM/EFS permission checks based on configuration

Changes

New Interface

  • Added optional CredentialValidator interface to pkg/provider/provider.go
  • Providers can opt-in to thorough credential validation

CLI Flag

  • Added --validate-creds flag to nic validate command
  • Shows helpful message for providers that don't support it

AWS Implementation

  • pkg/provider/aws/credentials.go: Core validation logic
    • getRequiredPermissions(): Config-aware permission list builder
    • validateCredentialsWithClients(): IAM Policy Simulator integration
    • ValidateCredentials(): Provider method implementation
  • Updated Validate() to use GetCallerIdentity for basic credential check

Permissions Checked

  • Always required: STS, S3 (state bucket), EC2 (core), EKS
  • Conditional: VPC creation (skip if existing_vpc_id), IAM roles (skip if existing_cluster_role_arn), EFS (only if enabled)

Test Plan

  • Unit tests for getRequiredPermissions() with various config combinations
  • Unit tests for validateCredentialsWithClients() with mocked AWS clients
  • Tests for error cases (invalid credentials, missing permissions)
  • All existing tests pass
  • golangci-lint passes with 0 issues
  • CLI help shows new --validate-creds flag

Usage

# Basic validation (silent credential check)
nic validate -f config.yaml

# Thorough credential validation
nic validate -f config.yaml --validate-creds

Related Issues

Comment thread pkg/provider/aws/credentials.go Outdated
Comment on lines +69 to +96
// Check permissions using IAM Policy Simulator
// Process in batches of 100 (API limit)
const batchSize = 100
var missingPerms []string

for i := 0; i < len(requiredPerms); i += batchSize {
end := i + batchSize
if end > len(requiredPerms) {
end = len(requiredPerms)
}
batch := requiredPerms[i:end]

simResult, err := iamClient.SimulatePrincipalPolicy(ctx, &iam.SimulatePrincipalPolicyInput{
PolicySourceArn: identity.Arn,
ActionNames: batch,
ResourceArns: []string{"*"},
})
if err != nil {
span.RecordError(err)
return nil, fmt.Errorf("failed to simulate IAM policy: %w", err)
}

for _, evalResult := range simResult.EvaluationResults {
if evalResult.EvalDecision != iamtypes.PolicyEvaluationDecisionTypeAllowed {
missingPerms = append(missingPerms, aws.ToString(evalResult.EvalActionName))
}
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this batch loop should be moved to utilities, since might be used elsewhere in the code. And IMO I don't like this being here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Replaced the hand-rolled batching loop with slices.Chunk from the Go 1.23+ stdlib (we're on Go 1.25). That removes the need for a custom utility while keeping the 100-action API limit explicit via the iamSimulateBatchSize constant.

Comment thread pkg/provider/aws/credentials.go Outdated
Comment on lines +113 to +145
func getRequiredPermissions(cfg *Config) []string {
perms := []string{
// STS - always required
"sts:GetCallerIdentity",

// S3 - state bucket management (always required)
"s3:HeadBucket",
"s3:CreateBucket",
"s3:PutBucketVersioning",
"s3:PutPublicAccessBlock",
"s3:ListObjectVersions",
"s3:DeleteObject",
"s3:DeleteBucket",

// EC2 - core (always required)
"ec2:DescribeAvailabilityZones",
"ec2:CreateTags",
"ec2:DeleteTags",

// EKS - always required
"eks:CreateCluster",
"eks:DeleteCluster",
"eks:DescribeCluster",
"eks:UpdateClusterVersion",
"eks:UpdateClusterConfig",
"eks:CreateNodegroup",
"eks:DeleteNodegroup",
"eks:DescribeNodegroup",
"eks:ListNodegroups",
"eks:UpdateNodegroupConfig",
"eks:TagResource",
"eks:UntagResource",
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This may be unnecessary, but would it make sense to keep the list of permissions in a separate file and reference it from the get method here?

I think that would make the permissions easier to locate in the codebase and would also be helpful from a documentation perspective.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good call. Moved the permission list to pkg/provider/aws/permissions.go and split it into awsBasePermissions, awsVPCPermissions, awsIAMPermissions, and awsEFSPermissions so each set is easy to find and audit. getRequiredPermissions now just composes them conditionally based on the cluster config.

@dcmcand dcmcand force-pushed the feature/aws-credential-validation branch from b377fb0 to 5686e10 Compare April 27, 2026 12:55
@dcmcand dcmcand requested a review from viniciusdc May 13, 2026 11:29
Adds an optional CredentialValidator interface to the provider package
and an AWS implementation that verifies the caller has all permissions
required for a Nebari deployment.

Default validation now uses sts:GetCallerIdentity instead of
Credentials.Retrieve, which only checks the local credential chain
without confirming AWS will accept them.

The new --validate-creds flag on the validate command runs the full
permission check via iam:SimulatePrincipalPolicy, batched in groups of
100 (the API limit) using slices.Chunk. Providers that don't implement
CredentialValidator print a note explaining the flag isn't supported.

The permission list lives in pkg/provider/aws/permissions.go to make
it easy to find and audit. Permissions are composed conditionally
based on cluster config:
  - VPC permissions skipped when ExistingVPCID is set
  - IAM permissions skipped when ExistingClusterRoleArn is set
  - EFS permissions only included when EFS.Enabled is true

Closes #6
@dcmcand dcmcand force-pushed the feature/aws-credential-validation branch from 5686e10 to 91089c0 Compare May 13, 2026 12:21

@khuyentran1401 khuyentran1401 May 27, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I validated the deploy/destroy permission set against a real AWS account (scoped IAM user, full nic deploy + nic destroy cycle). Two issues with the current list:

1. Three SDK operation names that aren't valid IAM actions (they match nothing, so grant no access):

current correct IAM action
s3:HeadBucket s3:ListBucket
s3:PutPublicAccessBlock s3:PutBucketPublicAccessBlock
s3:ListObjectVersions s3:ListBucketVersions

2. ~65 actions are missing. A from-scratch deploy + destroy needs 133 actions; this list has 71. Biggest gaps, each confirmed by an AccessDenied during testing:

  • elasticloadbalancing:* (5): nic destroy aborts at LB cleanup without these
  • s3:GetObject / PutObject / DeleteObjectVersion: state locking + versioned-bucket teardown
  • ssm:GetParameter: EKS AMI lookup (deploy fails at node-group planning)
  • logs:* (6), EKS add-on CRUD, access-entry + pod-identity APIs, IAM policy/OIDC-provider CRUD, launch templates + ec2:RunInstances

The full validated 133-action policy is here: https://github.com/nebari-dev/nebari-docs/blob/docs/aws-provider-howto/docs/static/policies/aws/nic-deploy.json

@dcmcand

dcmcand commented Jun 9, 2026

Copy link
Copy Markdown
Contributor Author

closed as stale

@dcmcand dcmcand closed this Jun 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement credential validation in AWS provider

3 participants