---
title: "Verify Bucket Access"
method: POST
path: "/v2/bucket-access/datasets/{dataset_id}/verify"
tags: ["Bucket Access"]
---

# Verify Bucket Access

`POST /v2/bucket-access/datasets/{dataset_id}/verify`

Read which principals are CURRENTLY on a SKU's bucket policy.

Read-only: never mutates the policy. One SKU maps to one bucket, so a single
call verifies every client on that SKU.

Callers use this to answer "does this client actually have access right now",
which no CAMS-side record can answer — the grant ledger and the sample
settings rows record what we *intended*, and a lost concurrent write makes
the two disagree.

Two outcomes are deliberately 200s with flags rather than HTTP errors,
because the caller must render them as "unknown" and a 4xx/5xx invites a
silent fallback to intent instead:

- ``bucket_found=false`` — the SKU or its bucket is not registered.
- ``read_ok=false``      — the live read failed (throttle, access-denied).
  ``principal_count`` is null and ``present``/``missing`` are empty; do NOT
  read this as "nobody has access".

Defined as sync ``def`` on purpose: BucketPolicyManager is fully blocking
(boto3 + a sync Postgres handle), so FastAPI runs this in its threadpool
rather than stalling the event loop.

## Path parameters

- `dataset_id` string, required

## Request body

- VerifyBucketAccessRequest
  - `lag` string, nullable — Lag of the dataset SKU. Null for the no-lag variant.
  - `cut` string, nullable — Cut of the dataset SKU. Null for the no-cut variant.
  - `principal_arns` string[] — ARNs to check for. Each is reported in `present` or `missing`. Pass an empty list to get only `principal_count`.

## Response `200`

Successful Response

- VerifyBucketAccessResponse
  - `dataset_id` string, required
  - `lag` string, nullable, required
  - `cut` string, nullable, required
  - `bucket_found` boolean, required
  - `read_ok` boolean, required
  - `principal_count` integer, nullable — Total client-access principals on the live policy. Null when the read failed — NOT zero, which would read as 'nobody has access'.
  - `present` string[], required
  - `missing` string[], required
  - `read_error` string, nullable — Why the read failed, when read_ok is false: invalid_credentials | no_credentials | access_denied | throttled | bucket_missing | unknown. A fixed vocabulary, never raw AWS text, since the caller renders it and AWS messages can carry bucket names and ARNs.
  - `checked_at` string, date-time, required

## Other responses

- `404` — Not Found
- `422` — Validation Error

---

[API](https://skmtc.net/carbonarc/apis/carbon-arc-api-documentation.md) · [All operations](https://skmtc.net/carbonarc/apis/carbon-arc-api-documentation/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/carbonarc/carbon-arc-api-documentation/revisions/4850d81778a4/schema)
