Description
This rule checks that the access keys used to authenticate to DigitalOcean Spaces (object storage) are rotated on a defined schedule — at least every 90 days. Static, long-lived keys widen the window in which a leaked key (via application logs, source control, or a compromised host) can be abused.
In the Control Panel, rotating a Spaces key is done with Regenerate key, which issues a new secret for the same key name. Spaces keys can now also be managed programmatically — create, list, update, and delete via the DigitalOcean API (/v2/spaces/keys) and doctl (doctl spaces keys). The rule reviews each key's age against the rotation policy and flags keys older than the threshold. Prefer scoped, per-bucket "limited" access keys over full-access keys so a rotation or revocation affects the smallest possible blast radius.
Remediation is to rotate keys on schedule, store the secrets in a managed secrets store instead of hardcoding them, and immediately regenerate or delete any key found exposed.
Spaces access keys older than 90 days with no regeneration in the window.
Full-access keys used where a limited, per-bucket key would suffice.
Keys embedded in application config or source control instead of a secrets manager.
Rationale
Object storage keys are S3-style credentials with broad reach over stored data; if one leaks and never rotates, an attacker retains access indefinitely. Regular rotation caps the useful lifetime of any leaked credential, and scoping keys per bucket limits how much a single compromised key can touch.
A predictable rotation cadence also forces the operational discipline — secrets storage, deploys that read from a secret store — that makes emergency revocation fast when a leak is discovered.
Impact
Pros:
Caps the lifetime, and therefore the value, of any leaked key.
Forces secrets to live in a managed store rather than in code.
Per-bucket limited keys shrink the blast radius of any single key.
Cons:
Rotation must be coordinated with every consumer of the key to avoid outages, and the new secret is shown only once when the key is created or regenerated.
There is no single "rotate" operation: rotation means regenerating the secret in the Control Panel, or creating a new key and deleting the old one via the API/doctl, then rolling every consumer over.
DigitalOcean does not expose a per-key "last rotated" timestamp (a Control Panel Regenerate keeps the same key), so age tracking against the rotation policy is largely manual or record-kept.
Default Value
DigitalOcean Spaces access keys do not expire or rotate automatically; they remain valid until you regenerate or delete them (in the Control Panel, or via the /v2/spaces/keys API or doctl spaces keys).
Pre-Requisite
Account role that can manage Spaces access keys (Control Panel or API/doctl).
An inventory of which applications or services use each key, so rotation can be coordinated.
A managed secrets store to hold the regenerated secret.
Remediation
Test Plan
Using the DigitalOcean Control Panel:
Sign in at cloud.digitalocean.com and click Spaces Object Storage in the left menu.
Open the Access Keys tab.
For each key, review its name, scope (limited vs full), and age against your records; identify keys not regenerated within the last 90 days.
Pass: every Spaces access key has been created or regenerated within the last 90 days (and scoped as narrowly as possible).
Fail: any key is older than 90 days without regeneration.
Using doctl or the API:
List Spaces access keys via the API or doctl and review each key's scope and age against your rotation records (the API exposes each key's created_at but not a separate last-regenerated timestamp).
doctl spaces keys list
curl -s -X GET -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/spaces/keys"
Pass: every Spaces access key was created or last rotated within the last 90 days (per your records) and is scoped as narrowly as possible. Fail: any key is older than 90 days with no rotation.
Implementation Steps
Using the DigitalOcean Control Panel:
Sign in at cloud.digitalocean.com and open Spaces Object Storage > Access Keys.
Recommended: if a full-access key is in use where a bucket-scoped key would do, click Create Access Key and create a Limited key scoped to the needed bucket(s) and permission level.
To rotate an existing key, find it, click the … menu, and choose Regenerate key; confirm by entering the key name.
Copy the new secret (shown once) into your secrets store and roll it out to every consumer.
Record the rotation date so the next 90-day cycle can be tracked.
Using doctl or the API:
Spaces access keys can be managed via the API (/v2/spaces/keys) or doctl (doctl spaces keys create/list/get/update/delete). There is no single rotate call: create a new key, roll every consumer over to it, then delete the old key. Prefer per-bucket grants to limit blast radius. The Control Panel's Regenerate key remains the way to reissue the secret for an existing key.
doctl spaces keys create <name> --grants 'bucket=<bucket>;permission=readwrite'
curl -s -X POST -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" -H "Content-Type: application/json" -d '{"name":"<name>","grants":[{"bucket":"<bucket>","permission":"readwrite"}]}' "https://api.digitalocean.com/v2/spaces/keys"
doctl spaces keys delete <access-key-id>
Backout Plan:
If a rotation breaks a consumer, the old secret cannot be recovered — regenerate the key again (or create a fresh key) and redeploy the correct secret to all consumers.
Keep the previous key active until every consumer is confirmed on the new secret, then delete the old key.