@@ -52,7 +52,7 @@ SKIP_NAMESPACES="kube-system,aiostack-test,myaiostack,aiostack,monitoring,gke-mc
5252COMMANDER_URL=" hq.aurva.ai:443"
5353INSECURE_SKIP_VERIFY=" true"
5454OBSERVER_VERSION=" latest"
55- OUTPOST_VERSION=" trueID-alpha "
55+ OUTPOST_VERSION=" latest "
5656CREATE_NAMESPACE=" true"
5757HELM_REPO_NAME=" aiostack"
5858HELM_REPO_URL=" https://charts.aurva.ai/"
@@ -61,10 +61,12 @@ DEPLOYMENT_TYPE="kubernetes"
6161CLOUD_PROVIDER=" aws"
6262REGION=" unknown"
6363CLUSTER_ID=" "
64+ IAM_ROLE_ARN=" "
65+ GCP_SERVICE_ACCOUNT=" "
6466
6567# State tracking
6668CURRENT_STEP=0
67- TOTAL_STEPS=7
69+ TOTAL_STEPS=8
6870HELM_REPO_ADDED=false
6971NAMESPACE_CREATED=false
7072INSTALLATION_STARTED=false
@@ -420,8 +422,7 @@ collect_credentials() {
420422 print_color " $BOLD$BRIGHT_GREEN " " Before proceeding, you need credentials from Aurva:"
421423 echo " "
422424 print_info " 1. Sign up for a free account (takes 30 seconds)"
423- print_info " 2. Check your registered email for your credentials:"
424- print_info " - Company ID"
425+ print_info " 2. Check your registered email for your Company ID"
425426 echo " "
426427
427428 # Ask if they want to open the signup page
@@ -534,6 +535,229 @@ collect_env_config() {
534535 print_success " Configuration completed"
535536}
536537
538+ # Collect IAM access configuration (AWS IRSA or GCP Workload Identity)
539+ collect_iam_config () {
540+ print_step " Configuring IAM Access"
541+
542+ echo " "
543+ print_info " The outpost needs cloud IAM access to enumerate roles in your account."
544+ echo " "
545+
546+ case " $CLOUD_PROVIDER " in
547+ aws) _collect_aws_iam_config ;;
548+ gcp) _collect_gcp_iam_config ;;
549+ * )
550+ print_warning " Cloud provider '${CLOUD_PROVIDER} ' — IAM fetch not supported yet."
551+ print_info " Skipping IAM access configuration."
552+ ;;
553+ esac
554+ }
555+
556+ _collect_aws_iam_config () {
557+ print_color " $BOLD " " AWS IAM Access via IRSA (IAM Roles for Service Accounts)"
558+ echo " "
559+ print_info " The outpost assumes an IAM role through IRSA to call read-only APIs."
560+ print_info " Required permissions on the role:"
561+ echo " "
562+ print_color " $WHITE " " IAM inventory:"
563+ print_color " $WHITE " " iam:ListRoles iam:GetRole"
564+ print_color " $WHITE " " iam:ListAttachedRolePolicies iam:GetPolicy iam:GetPolicyVersion"
565+ print_color " $WHITE " " iam:ListRolePolicies iam:GetRolePolicy"
566+ echo " "
567+ print_color " $WHITE " " RDS datasource inventory:"
568+ print_color " $WHITE " " rds:DescribeDBInstances rds:DescribeDBClusters"
569+ print_color " $WHITE " " rds:DescribeDBSubnetGroups rds:ListTagsForResource"
570+ echo " "
571+ print_color " $WHITE " " S3 datasource inventory:"
572+ print_color " $WHITE " " s3:ListAllMyBuckets s3:GetBucketLocation"
573+ print_color " $WHITE " " s3:GetBucketPublicAccessBlock s3:GetBucketTagging"
574+ print_color " $WHITE " " s3:GetBucketVersioning s3:GetBucketAcl"
575+ echo " "
576+
577+ # Attempt to derive account ID and OIDC issuer automatically
578+ local aws_account_id=" " oidc_issuer=" " cluster_name=" "
579+
580+ if [[ " $CLUSTER_ID " =~ arn:aws:eks:[^:]+:([^:]+):cluster/(.+)$ ]]; then
581+ aws_account_id=" ${BASH_REMATCH[1]} "
582+ cluster_name=" ${BASH_REMATCH[2]} "
583+ fi
584+
585+ if command -v aws & > /dev/null; then
586+ print_info " AWS CLI detected — fetching account and OIDC details..."
587+ if [[ -z " $aws_account_id " ]]; then
588+ aws_account_id=$( aws sts get-caller-identity --query Account --output text 2> /dev/null || echo " " )
589+ fi
590+ if [[ -n " $cluster_name " && -n " $REGION " && " $REGION " != " unknown" ]]; then
591+ oidc_issuer=$( aws eks describe-cluster \
592+ --name " $cluster_name " --region " $REGION " \
593+ --query " cluster.identity.oidc.issuer" \
594+ --output text 2> /dev/null | sed ' s|https://||' || echo " " )
595+ fi
596+ if [[ -n " $aws_account_id " ]]; then
597+ print_success " Account ID: ${aws_account_id} "
598+ fi
599+ if [[ -n " $oidc_issuer " ]]; then
600+ print_success " OIDC issuer: ${oidc_issuer} "
601+ fi
602+ echo " "
603+ fi
604+
605+ local acct=" ${aws_account_id:- YOUR_ACCOUNT_ID} "
606+ local oidc=" ${oidc_issuer:- oidc.eks.${REGION} .amazonaws.com/ id/ YOUR_OIDC_ID} "
607+ local role_name=" aiostack-outpost-secure-readonly-role"
608+ local sa_name=" aiostack-outpost-sa"
609+ local role_arn=" arn:aws:iam::${acct} :role/${role_name} "
610+
611+ print_color " $BOLD$BRIGHT_GREEN " " Run these commands to create the role (copy-paste ready):"
612+ echo " "
613+ cat << AWSCMDS
614+ # 1. Create the IAM policy
615+ aws iam create-policy \\
616+ --policy-name AIOStackOutpostSecureReadOnlyPolicy \\
617+ --policy-document '{
618+ "Version": "2012-10-17",
619+ "Statement": [
620+ {
621+ "Sid": "IAMInventory",
622+ "Effect": "Allow",
623+ "Action": [
624+ "iam:ListRoles","iam:GetRole",
625+ "iam:ListAttachedRolePolicies","iam:GetPolicy","iam:GetPolicyVersion",
626+ "iam:ListRolePolicies","iam:GetRolePolicy"
627+ ],
628+ "Resource": "*"
629+ },
630+ {
631+ "Sid": "RDSDatasourceInventory",
632+ "Effect": "Allow",
633+ "Action": [
634+ "rds:DescribeDBInstances",
635+ "rds:DescribeDBClusters",
636+ "rds:DescribeDBSubnetGroups",
637+ "rds:ListTagsForResource"
638+ ],
639+ "Resource": "*"
640+ },
641+ {
642+ "Sid": "S3DatasourceInventory",
643+ "Effect": "Allow",
644+ "Action": [
645+ "s3:ListAllMyBuckets",
646+ "s3:GetBucketLocation",
647+ "s3:GetBucketPublicAccessBlock",
648+ "s3:GetBucketTagging",
649+ "s3:GetBucketVersioning",
650+ "s3:GetBucketAcl"
651+ ],
652+ "Resource": "*"
653+ }
654+ ]
655+ }'
656+
657+ # 2. Create the role with OIDC trust for this cluster's service account
658+ aws iam create-role \\
659+ --role-name ${role_name} \\
660+ --assume-role-policy-document '{
661+ "Version": "2012-10-17",
662+ "Statement": [{
663+ "Effect": "Allow",
664+ "Principal": {"Federated": "arn:aws:iam::${acct} :oidc-provider/${oidc} "},
665+ "Action": "sts:AssumeRoleWithWebIdentity",
666+ "Condition": {"StringEquals": {
667+ "${oidc} :sub": "system:serviceaccount:${NAMESPACE} :${sa_name} ",
668+ "${oidc} :aud": "sts.amazonaws.com"
669+ }}
670+ }]
671+ }'
672+
673+ # 3. Attach the policy to the role
674+ aws iam attach-role-policy \\
675+ --role-name ${role_name} \\
676+ --policy-arn arn:aws:iam::${acct} :policy/AIOStackOutpostSecureReadOnlyPolicy
677+ AWSCMDS
678+
679+ echo " "
680+ print_info " Expected role ARN: ${role_arn} "
681+ echo " "
682+
683+ while true ; do
684+ IAM_ROLE_ARN=$( prompt " Paste your IAM Role ARN (press Enter to skip)" " " )
685+ IAM_ROLE_ARN=$( echo " $IAM_ROLE_ARN " | xargs)
686+
687+ if [[ -z " $IAM_ROLE_ARN " ]]; then
688+ print_warning " No IAM role provided — outpost will not be able to enumerate IAM roles, RDS instances, or S3 buckets."
689+ break
690+ elif [[ " $IAM_ROLE_ARN " =~ ^arn:aws:iam::[0-9]{12}:role/.+$ ]]; then
691+ print_success " IAM role ARN accepted."
692+ break
693+ else
694+ print_error " That doesn't look like a valid IAM role ARN."
695+ print_info " Expected format: arn:aws:iam::123456789012:role/role-name"
696+ fi
697+ done
698+ }
699+
700+ _collect_gcp_iam_config () {
701+ print_color " $BOLD " " GCP IAM Access via Workload Identity"
702+ echo " "
703+ print_info " The outpost impersonates a GCP Service Account to call IAM read APIs."
704+ print_info " The service account needs roles/iam.securityReviewer (or equivalent)."
705+ echo " "
706+
707+ local project_id=" "
708+ if command -v gcloud & > /dev/null; then
709+ project_id=$( gcloud config get-value project 2> /dev/null || echo " " )
710+ if [[ -n " $project_id " ]]; then
711+ print_success " GCP project: ${project_id} "
712+ echo " "
713+ fi
714+ fi
715+
716+ local proj=" ${project_id:- YOUR_PROJECT_ID} "
717+ local gsa_name=" aiostack-outpost"
718+ local gsa_email=" ${gsa_name} @${proj} .iam.gserviceaccount.com"
719+ local ksa_name=" aiostack-outpost-sa"
720+
721+ print_color " $BOLD$BRIGHT_GREEN " " Run these commands to set up Workload Identity (copy-paste ready):"
722+ echo " "
723+ cat << GCPCMDS
724+ # 1. Create the GCP Service Account
725+ gcloud iam service-accounts create ${gsa_name} \\
726+ --project=${proj} \\
727+ --display-name="AIOStack Outpost"
728+
729+ # 2. Grant IAM read permissions
730+ gcloud projects add-iam-policy-binding ${proj} \\
731+ --member="serviceAccount:${gsa_email} " \\
732+ --role="roles/iam.securityReviewer"
733+
734+ # 3. Allow the Kubernetes SA to impersonate the GCP SA
735+ gcloud iam service-accounts add-iam-policy-binding ${gsa_email} \\
736+ --role="roles/iam.workloadIdentityUser" \\
737+ --member="serviceAccount:${proj} .svc.id.goog[${NAMESPACE} /${ksa_name} ]"
738+ GCPCMDS
739+
740+ echo " "
741+ print_info " Expected service account email: ${gsa_email} "
742+ echo " "
743+
744+ while true ; do
745+ GCP_SERVICE_ACCOUNT=$( prompt " Paste your GCP Service Account email (press Enter to skip)" " " )
746+ GCP_SERVICE_ACCOUNT=$( echo " $GCP_SERVICE_ACCOUNT " | xargs)
747+
748+ if [[ -z " $GCP_SERVICE_ACCOUNT " ]]; then
749+ print_warning " No GCP SA provided — outpost will not be able to enumerate IAM roles."
750+ break
751+ elif [[ " $GCP_SERVICE_ACCOUNT " =~ ^[^@]+@[^@]+\. iam\. gserviceaccount\. com$ ]]; then
752+ print_success " GCP service account accepted."
753+ break
754+ else
755+ print_error " That doesn't look like a valid GCP service account email."
756+ print_info " Expected format: name@project.iam.gserviceaccount.com"
757+ fi
758+ done
759+ }
760+
537761# Review configuration
538762review_config () {
539763 print_step " Reviewing Configuration"
@@ -568,6 +792,16 @@ review_config() {
568792 echo " Cluster ID: ${CLUSTER_ID} "
569793 echo " "
570794
795+ print_color " $BOLD " " IAM Access:"
796+ if [[ -n " $IAM_ROLE_ARN " ]]; then
797+ echo " AWS IAM Role ARN: ${IAM_ROLE_ARN} "
798+ elif [[ -n " $GCP_SERVICE_ACCOUNT " ]]; then
799+ echo " GCP Service Account: ${GCP_SERVICE_ACCOUNT} "
800+ else
801+ echo " IAM Access: not configured (IAM fetch disabled)"
802+ fi
803+ echo " "
804+
571805 # Show the helm command
572806 print_color " $BOLD$BRIGHT_GREEN " " Helm command that will be executed:"
573807 print_color " $GREEN " " helm install ${RELEASE_NAME} ${HELM_CHART} \\ "
@@ -625,6 +859,8 @@ deploymentType: ${DEPLOYMENT_TYPE}
625859cloudProvider: ${CLOUD_PROVIDER}
626860region: ${REGION}
627861clusterId: ${CLUSTER_ID}
862+ iamRoleArn: ${IAM_ROLE_ARN}
863+ gcpServiceAccount: ${GCP_SERVICE_ACCOUNT}
628864EOF
629865
630866 chmod 600 " $config_file "
@@ -662,6 +898,8 @@ load_config() {
662898 cloudProvider) CLOUD_PROVIDER=" $value " ;;
663899 region) REGION=" $value " ;;
664900 clusterId) CLUSTER_ID=" $value " ;;
901+ iamRoleArn) IAM_ROLE_ARN=" $value " ;;
902+ gcpServiceAccount) GCP_SERVICE_ACCOUNT=" $value " ;;
665903 esac
666904 done < " $config_file "
667905
@@ -742,6 +980,13 @@ install_aurva() {
742980 --set " outpost.version=${OUTPOST_VERSION} "
743981 )
744982
983+ if [[ -n " $IAM_ROLE_ARN " ]]; then
984+ helm_cmd+=(--set " outpost.serviceAccount.aws.iamRoleArn=${IAM_ROLE_ARN} " )
985+ fi
986+ if [[ -n " $GCP_SERVICE_ACCOUNT " ]]; then
987+ helm_cmd+=(--set " outpost.serviceAccount.gcp.serviceAccount=${GCP_SERVICE_ACCOUNT} " )
988+ fi
989+
745990 print_verbose " Running: ${helm_cmd[*]} "
746991
747992 # Execute helm install
@@ -966,6 +1211,7 @@ main() {
9661211
9671212 configure_namespace
9681213 collect_env_config
1214+ collect_iam_config
9691215 review_config
9701216 install_aurva
9711217 verify_deployment
0 commit comments