Skip to main content
fjall unlock recovers a resource that a stranded deny policy has locked everyone out of. It is a break-glass command. It runs an STS AssumeRoot session in the member account that owns the resource, because a quarantine deny blocks every role principal, including the cascade role Fjall normally deploys with.
The unlock is not a repair. It deletes the bucket’s entire policy: the stranded deny, but also any enforceSSL TLS-only deny and every legitimate access grant the policy carried. Re-put sane statements as soon as the unlock completes.
This command does not read infrastructure.ts and does not take -a, --app. Run it from anywhere.

Unlock a quarantined bucket

Run it without the acknowledgement first. The CLI prints the exact consequences and the re-run command, then exits without calling AWS.
Re-run with the flag once you have read the refusal:
Pass the region when the bucket does not live in the root profile’s home region:
bucket is the only subcommand. fjall unlock on its own reports that no subcommand was specified and lists bucket.

What Happens

  1. Options are validated. The bucket name must be 3 to 63 characters and --account must be a 12-digit AWS account id.
  2. The CLI requires an authenticated session.
  3. Without --acknowledge-root-session, the command refuses. It prints what the root session does, what the delete destroys, and the exact command to re-run. No AWS call is made.
  4. It resolves the organisation root profile from your org config. If no organisation account is connected, the command stops and points you at fjall connect.
  5. It picks the region: --region first, then the root profile’s home region, then us-east-2. AssumeRoot needs a regional STS endpoint, so the region is load-bearing.
  6. It assumes root in the member account, bounded by the AWS managed root-task policy arn:aws:iam::aws:policy/root-task/S3UnlockBucketPolicy for a maximum of 900 seconds.
  7. It captures the live policy with GetBucketPolicy, then removes it with DeleteBucketPolicy. Capture runs first on purpose: DeleteBucketPolicy does not record the policy body in CloudTrail, so the captured JSON is the only forensic copy.
  8. It prints the captured policy (credential-masked) and the loss warning.

After the unlock

CloudFormation does not reconcile an out-of-band policy deletion on the next deploy. Review the captured policy and re-put the statements the bucket needs, starting with the TLS-only deny. For a finding raised by a compliance scan, fjall compliance fix --issue-id <id> --execute --acknowledge-root-session runs the remediation for that issue behind the same root-session gate.

Bucket with no policy

If the bucket carries no policy at all, it is not policy-locked. The command reports that there is nothing to unlock and deletes nothing.

No dry run

There is no --dry-run flag. The refusal in step 3 is the preview: it names the account, the bucket, the region and the consequences before anything is touched.

Agent mode

With --agent, a missing acknowledgement emits an action_required block with the action root_session_acknowledgement_required and a choice carrying the full re-run command. An agent can resolve it on its own, no human input required. A successful unlock returns these fields:

Options

All flags below belong to fjall unlock bucket. The parent fjall unlock group accepts --non-interactive.

Next Steps

S3 Bucket

Declare bucket policy and encryption settings in infrastructure.ts.

fjall drift

Detect and repair infrastructure changed outside CloudFormation.

fjall connect

Connect the organisation and member AWS accounts the unlock relies on.

Deploy the organisation

Set up the organisation tier that enables centralised root access.