Cosmoner Docs
API Reference

IAM

AWS credentials a project has issued for object storage and container registries.

Some AWS-native tooling cannot use a Cosmoner API key — aws ecr get-login-password, Kubernetes image pull secrets, S3 clients. These endpoints issue scoped AWS credentials for those cases and list every credential a project has out there.

Cosmoner API keys are a different thing and are not listed here — see API Keys.

List Credentials

GET /v1/projects/:projectId/iam

Returns every AWS credential the project has issued as one list. A credential can cover both services at once, so it is listed once with a registry and a storage half — either is null when the credential does not reach that service. errors carries whatever could not be reached: a service that is having a bad day reports itself instead of failing the request.

{
  "success": true,
  "data": {
    "credentials": [
      {
        "iamUserName": "dbd-iam-<projectId>-ci-pipeline",
        "label": "ci-pipeline",
        "accessKeyId": "AKIA…",
        "createdAt": "2026-08-04T12:00:00.000Z",
        "origin": "project",
        "registry": {
          "access": "push",
          "allRepositories": false,
          "repositories": [
            {
              "repositoryId": "cmsh95uld0000ce9kkchanq4y",
              "repositoryName": "frontend",
              "registryId": "cmsh95uld0000ce9kkchanq4z"
            }
          ]
        },
        "storage": {
          "access": "write",
          "allBuckets": false,
          "buckets": [{ "bucketId": "…", "bucketName": "assets" }]
        }
      }
    ],
    "errors": []
  }
}

origin says which shape a credential has. project credentials are the current model, may span both services, and are the only ones that can be re-scoped. registry and bucket are the two older single-service shapes — still listed and still working, with the scope they were created with.

allRepositories and allBuckets mean the grant covers everything in the project, including resources created later. The repositories and buckets arrays alongside them then list what exists today, which is not the boundary — do not read them as the grant.

Auth: Required (member, scope: iam:read)

Get Credentials

GET /v1/projects/:projectId/iam/:iamUserName

Returns one credential in the same shape the list uses. Returns 404 if the project has no credential by that name.

Auth: Required (member, scope: iam:read)

Create Credentials

POST /v1/projects/:projectId/iam
{
  "label": "ci-pipeline",
  "registry": { "access": "push", "repositoryIds": ["cmsh95uld0000ce9kkchanq4y"] },
  "storage": { "access": "write", "bucketIds": [] }
}
FieldDefaultNotes
label—1–20 characters. Must be unique within the project; it becomes part of the IAM user name.
registrynullOmit or set to null for a credential that reaches no registry.
registry.accesspullpull is read-only. push also allows uploading images.
registry.repositoryIds[]Repositories the credential reaches. Empty means every repository in the project, including ones created later.
storagenullOmit or set to null for a credential that reaches no bucket.
storage.accesswriteread allows downloading and listing. write also allows uploading and deleting.
storage.bucketIds[]Buckets the credential reaches. Empty means every bucket in the project, including ones created later.

At least one of registry and storage is required — a credential that reaches nothing is a key you have to rotate for no benefit.

The response includes secretAccessKey, which is returned once and never stored. Lost secrets cannot be recovered — delete the credential and create a new one.

Registry scoping stops at the repository: an ECR repository name carries the project and the repository but not the registry it was created under, so a credential can name individual repositories or cover the whole project, but not one registry within it. Pulls made with it go straight from AWS to the client and are not metered as egress; storage is billed as usual.

Returns 404 if registry is set and the project has no container registry, or if any id in registry.repositoryIds or storage.bucketIds does not belong to the project.

Auth: Required (member, write access, scope: iam:write)

Update Credentials

PATCH /v1/projects/:projectId/iam/:iamUserName
{
  "registry": { "access": "push", "repositoryIds": ["cmsh95uld0000ce9kkchanq4y"] },
  "storage": { "access": "read", "bucketIds": [] }
}

Rewrites what the credential reaches, keeping the same access key — nothing using it has to be reissued. registry and storage take the same fields as on create, and both halves are applied in full: a half sent as null or omitted is dropped from the credential, so send the halves you want it to keep. At least one of them is required.

The label cannot be changed. It is part of the credential's name in AWS, so a different label is a different credential: create a new one and delete this.

Returns the credential as it now reads, resolved the same way the list resolves it. Returns 400 for a credential with origin of registry or bucket — those are fixed at the scope they were created with — and 404 if the credential no longer exists.

Auth: Required (member, write access, scope: iam:write)

Delete Credentials

DELETE /v1/projects/:projectId/iam/:iamUserName

Deletes the IAM user and its access keys, whichever origin it has. Anything using the key stops working immediately. Returns 403 if the credential belongs to another project.

Auth: Required (member, write access, scope: iam:write)

Create Registry Credentials (legacy)

POST /v1/projects/:projectId/iam/container-registry
{
  "label": "ci-pipeline",
  "access": "push",
  "repositoryId": "cmsh95uld0000ce9kkchanq4y"
}

The registry-only shape, kept for callers written against it. It creates a credential with origin: "registry", which cannot be widened to object storage afterwards. Prefer POST /v1/projects/:projectId/iam.

Auth: Required (member, write access, scope: iam:write)

Delete Registry or Bucket Credentials (legacy)

DELETE /v1/projects/:projectId/iam/container-registry/:iamUserName
DELETE /v1/projects/:projectId/iam/object-storage/:bucketId/:iamUserName

Both do what DELETE /v1/projects/:projectId/iam/:iamUserName does, for their one shape. The bucket-only create endpoint they pair with is documented under Object Storage and is likewise legacy — credentials made there cannot be re-scoped afterwards.

Auth: Required (member, write access, scope: iam:write)

On this page