Managing Cloud Credentials
Cloud credentials allow OpenPrime to interact with your cloud providers for deploying infrastructure.
Security Model​
Credentials are:
- Encrypted at rest using AES-256-GCM
- User-scoped - each user manages their own credentials
- Never logged - sensitive values are masked in logs
Adding Credentials​
AWS Credentials​
- Navigate to Settings → Cloud Credentials
- Click Add Credential → AWS
- Enter:
- Name: Descriptive identifier
- Access Key ID: Your AWS access key
- Secret Access Key: Your AWS secret key
- Default Region: Primary region
{
"provider": "aws",
"name": "production-aws",
"accessKeyId": "AKIA...",
"secretAccessKey": "...",
"defaultRegion": "us-east-1"
}
IAM Policy Requirements​
Two separate things need permissions, and it is easy to grant only the first:
- Provisioning your infrastructure — what the generated Terraform applies.
- Creating the Terraform state backend — the S3 bucket OpenPrime creates for you before any Terraform runs.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Provisioning",
"Effect": "Allow",
"Action": [
"eks:*",
"ec2:*",
"iam:*",
"autoscaling:*",
"elasticloadbalancing:*"
],
"Resource": "*"
},
{
"Sid": "StateBackendBucket",
"Effect": "Allow",
"Action": [
"s3:CreateBucket",
"s3:ListBucket",
"s3:GetBucketTagging",
"s3:PutBucketTagging",
"s3:PutEncryptionConfiguration",
"s3:PutBucketVersioning",
"s3:PutBucketPublicAccessBlock"
],
"Resource": "arn:aws:s3:::*"
},
{
"Sid": "StateObjects",
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject"],
"Resource": "arn:aws:s3:::*/*"
}
]
}
Without the s3: statements above, creating an environment's state backend fails
before Terraform is ever invoked. A policy covering only eks/ec2/iam looks
sufficient and is not.
Terraform state is locked with S3 native locking — the generated backend block
contains use_lockfile = true and no dynamodb_table, and locks appear as
.tflock objects beside the state file. The s3:PutObject / s3:DeleteObject
grants above already cover them.
Earlier versions of this page listed dynamodb:CreateTable, dynamodb:DescribeTable
and dynamodb:DeleteTable as required. They were not, and granting them was
unnecessary privilege. A DynamoDB code path still exists in StateCraft for callers
that request lockingMechanism: "dynamodb" explicitly through the API; the wizard
never does — it sends "s3".
The statements above are exactly the S3 calls StateCraft makes: CreateBucket,
PutBucketVersioning, PutBucketEncryption, PutPublicAccessBlock,
PutBucketTagging, plus HeadBucket and GetBucketTagging for the ownership
checks.
Deleting an environment​
Tearing down a state backend needs more than creating one, because the bucket is versioned and every version has to be removed before it will delete. Add these only if you want OpenPrime to be able to destroy backends:
{
"Effect": "Allow",
"Action": [
"s3:DeleteBucket",
"s3:ListBucketVersions",
"s3:DeleteObjectVersion"
],
"Resource": "*"
}
"Resource": "*" keeps the example readable. In a real account, restrict the S3
statements to the bucket name you configure for the backend, which OpenPrime
derives as <account-id>-terraform-<environment>.
The bucket survives teardown by design — losing state is worse than keeping an empty bucket. Nothing in the product offers to remove it, so a long-lived account accumulates one bucket per environment ever created.
Azure Credentials​
- Click Add Credential → Azure
- Enter:
- Name: Descriptive identifier
- Subscription ID: Your Azure subscription
- Tenant ID: Azure AD tenant
- Client ID: Service principal app ID
- Client Secret: Service principal secret
{
"provider": "azure",
"name": "production-azure",
"subscriptionId": "...",
"tenantId": "...",
"clientId": "...",
"clientSecret": "..."
}
GCP Credentials​
- Click Add Credential → GCP
- Upload or paste service account JSON:
{
"provider": "gcp",
"name": "production-gcp",
"projectId": "my-project",
"serviceAccountKey": { ... }
}
Using Credentials​
Assigning to Environments​
When creating/editing an environment:
- Select the Cloud Credential dropdown
- Choose the appropriate credential
- Credential is referenced, not copied
Generated Code​
Credentials are referenced in generated Terraform:
# AWS provider
provider "aws" {
region = var.aws_region
# Credentials via environment variables
}
Set environment variables when running Terraform:
export AWS_ACCESS_KEY_ID="..."
export AWS_SECRET_ACCESS_KEY="..."
terraform apply
Credential Rotation​
Updating Credentials​
- Navigate to Settings → Cloud Credentials
- Click Edit on the credential
- Update the secret values
- Save changes
Existing environments using this credential will use new values on next deployment.
Best Practices​
- Rotate regularly - Every 90 days recommended
- Use least privilege - Minimal permissions needed
- Separate by environment - Production vs. development
- Monitor usage - Enable CloudTrail/Activity Logs
Troubleshooting​
"Invalid credentials" Error​
- Verify credentials are correct
- Check IAM permissions
- Ensure region is correct
- Test with AWS CLI:
aws sts get-caller-identity
Credentials Not Listed​
- Refresh the page
- Check browser console for errors
- Verify you're logged in as correct user