bucket/create FormID 20500
Create a new S3 bucket with encryption, versioning, and access controls.
When to Use
- Tenant environment provisioning: Automatically create a dedicated S3 bucket when a new tenant is onboarded, applying standard encryption and access block policies.
- Per-environment bucket setup: Provision separate dev, staging, and prod buckets at workflow start to isolate data between environments.
- Backup destination creation: Create a timestamped backup bucket at the start of a scheduled backup workflow before writing any data.
- Media storage provisioning: Set up an application-specific bucket with the correct ACL and CORS settings when deploying a new application module.
- Compliance archive bucket: Create a KMS-encrypted, versioned bucket with all public access blocked for regulated data retention workflows.
Configuration
Connection
Credentials and region are not fields on this operation. Wire an S3 Server satellite node into this node's input. The satellite holds the vault credential (
ApiKey type — Username = access key ID, Password = secret key), the target AWS region, and an optional Service URL override for S3-compatible backends. Its values are merged onto this node at execution time and take precedence over anything set locally. See S3 Server (satellite) for the full field reference.
Operation Fields
| Field | Required | Description |
|---|---|---|
bucketName | Required | Globally unique bucket name. 3–63 lowercase characters; letters, numbers, and hyphens only. Must not look like an IP address. |
cannedAcl | Optional | Canned ACL: private (default), public-read, public-read-write, authenticated-read. Default: private. |
serverSideEncryption | Optional | Encryption algorithm: AES256 (default), aws:kms, none. Default: AES256. |
kmsKeyId | Optional | KMS key ARN or alias. Required when serverSideEncryption is aws:kms. |
enableVersioning | Optional | Enable S3 versioning on the bucket. Default: false. Recommended for buckets subject to automated deletions. |
blockPublicAcls | Optional | Block new public ACLs and public ACL uploads. Default: true. |
blockPublicPolicy | Optional | Block new public bucket policies. Default: true. |
ignorePublicAcls | Optional | Ignore public ACLs even if set. Default: true. |
restrictPublicBuckets | Optional | Restrict access to buckets with public policies to only AWS services and authorized users. Default: true. |
Sample Configuration
// Credentials + region resolved from the connected S3 Server satellite — see s3-server-satellite.html
{
"resource": "bucket",
"operation": "create",
"bucketName": "acme-tenant-{{ $node.TenantOnboard.output.tenantSlug }}-docs",
"cannedAcl": "private",
"serverSideEncryption": "AES256",
"enableVersioning": true,
"blockPublicAcls": true,
"blockPublicPolicy": true,
"ignorePublicAcls": true,
"restrictPublicBuckets": true
}
Validation Errors
| Error Code | Cause & Resolution |
|---|---|
MISSING_BUCKET_NAME | Design-time validation: bucketName was left blank. Fails before any request is sent. |
INVALID_BUCKET_NAME | Design-time validation: name fails length (3–63 chars), character set (lowercase/digits/hyphens/dots), start/end, consecutive-dot, xn---prefix, -s3alias-suffix, or IPv4-shape checks. |
MISSING_KMS_KEY / INVALID_KMS_KEY | Design-time validation: serverSideEncryption is aws:kms but kmsKeyId is blank or outside the 8–2048 char range. |
BucketAlreadyExists | Raw AWS error: a bucket with this name already exists in a different AWS account. S3 bucket names are globally unique — choose a different name. |
BucketAlreadyOwnedByYou | Raw AWS error: the bucket already exists in your account. If the intent was idempotent provisioning, check downstream logic to skip creation when this error occurs. |
AccessDenied | Raw AWS error: the IAM identity lacks s3:CreateBucket permission. Update the IAM policy to include s3:CreateBucket and s3:PutBucketPolicy as needed. |
InvalidLocationConstraint | Raw AWS error: the specified region is invalid or the bucket creation request conflicts with the region constraint. Verify the connected satellite's region value. |
Output
Success Port
| Field | Type | Description |
|---|---|---|
status | string | success on successful bucket creation. |
errorCode | string | Empty string on success. |
bucketName | string | The name of the created bucket. |
bucketArn | string | Full ARN of the bucket, e.g. arn:aws:s3:::my-bucket. |
region | string | AWS region where the bucket was created. |
createdAt | string | ISO 8601 timestamp of bucket creation. |
versioningStatus | string | Enabled or Suspended depending on the enableVersioning setting. |
Error Port
On failure, the error port activates with errorCode (e.g. BucketAlreadyExists), errorMessage (human-readable description), and httpStatusCode from the AWS API response. Route to a notification or compensation node.
Sample Output
{
"status": "success",
"errorCode": "",
"bucketName": "acme-tenant-northstar-docs",
"bucketArn": "arn:aws:s3:::acme-tenant-northstar-docs",
"region": "us-east-1",
"createdAt": "2026-05-26T10:14:33Z",
"versioningStatus": "Enabled"
}
Expression Reference
| Expression | Result |
|---|---|
{{ $node.CreateBucket.output.bucketName }} | The created bucket name — use in subsequent upload or policy nodes. |
{{ $node.CreateBucket.output.bucketArn }} | Full ARN — use in IAM policy attachment or SNS notification nodes. |
{{ $node.CreateBucket.output.region }} | Region string — pass to downstream S3 nodes targeting the same bucket. |
{{ $node.CreateBucket.output.createdAt }} | Creation timestamp — log to audit trail or emit in confirmation notification. |
{{ $node.CreateBucket.output.versioningStatus }} | Confirm versioning was applied — use in conditional post-provision checks. |
Node Policies & GuardRails
| Policy Area | Recommendation |
|---|---|
| Credential Storage | Store accessKeyId and secretKey in BizFirst Credentials Manager. Never hardcode in workflow configuration. |
| IAM Permissions | Grant s3:CreateBucket, s3:PutBucketEncryption, s3:PutBucketVersioning, and s3:PutBucketPublicAccessBlock — nothing more. |
| Default ACL | Always use private ACL. Never configure public-read-write without a reviewed security exception. |
| Encryption Default | Always set serverSideEncryption to at least AES256 for all buckets. Use aws:kms for PII or regulated data. |
| Public Access Block | Leave all four public access block settings as true unless the bucket explicitly serves public static assets. |
| Versioning on Critical Buckets | Set enableVersioning: true for any bucket that will receive automated writes or deletions. |
| Idempotency | Handle BucketAlreadyOwnedByYou gracefully in workflow error routing — re-provisioning scenarios should not fail the workflow. |
| Bucket Name Pattern | Use consistent naming conventions (e.g. {company}-{tenant}-{purpose}) to prevent collisions and support IAM wildcard policies. |
Examples
Example 1: Tenant Onboarding — Create Isolated Storage
When a new tenant completes signup, a workflow provisions their dedicated S3 bucket with KMS encryption and versioning enabled.
// Node: CreateTenantBucket (S3 — bucket/create)
{
"bucketName": "bfai-tenant-{{ $node.TenantRecord.output.tenantId }}-storage",
"serverSideEncryption": "aws:kms",
"kmsKeyId": "arn:aws:kms:us-east-1:123456789012:key/mrk-abc123",
"enableVersioning": true,
"blockPublicAcls": true,
"blockPublicPolicy": true,
"ignorePublicAcls": true,
"restrictPublicBuckets": true
}
// Next node: RecordBucketArn (Variable Assignment)
// Sets $workflow.tenantBucketArn = {{ $node.CreateTenantBucket.output.bucketArn }}
Example 2: CI/CD Pipeline — Per-Environment Provisioning
A deployment workflow creates environment-specific buckets if they do not yet exist, using error routing to skip BucketAlreadyOwnedByYou and proceed.
// Node: CreateEnvBucket (S3 — bucket/create)
{
"bucketName": "myapp-{{ $node.DeployConfig.output.environment }}-artifacts",
"cannedAcl": "private",
"serverSideEncryption": "AES256",
"enableVersioning": false
}
// Error port route: IF errorCode == "BucketAlreadyOwnedByYou" → Continue
// Success port route: LogBucketCreation → UploadArtifacts
Example 3: Compliance Archive Bucket Setup
A quarterly compliance workflow creates a WORM-style archive bucket with all public access blocked and KMS encryption for regulated financial records.
// Node: CreateArchiveBucket (S3 — bucket/create)
{
"bucketName": "acme-compliance-archive-{{ $now | date: 'YYYY-Q' }}",
"cannedAcl": "private",
"serverSideEncryption": "aws:kms",
"kmsKeyId": "{{ $env.COMPLIANCE_KMS_KEY_ARN }}",
"enableVersioning": true,
"blockPublicAcls": true,
"blockPublicPolicy": true,
"ignorePublicAcls": true,
"restrictPublicBuckets": true
}
// Next: NotifyComplianceTeam with bucketArn in message body