Operations and observability
Object data belongs on the S3 or native client. Tenant provisioning, key rotation, quotas, usage, and audit queries belong on the admin client against the private admin listener.
Health and readiness
Native and admin clients expose typed healthz and readyz probes in Node and Java; the Go native/admin packages expose the matching health methods. Probe requests do not send object or admin credentials. Health means the process answers; readiness includes dependency/component state and is the safer load-balancer gate.
health, err := admin.Health(ctx)
ready, err := admin.Readiness(ctx)
fmt.Println(health.Status, ready.Status)const health = await admin.healthz({ signal, timeoutMs: 2_000 });
const ready = await admin.readyz({ signal, timeoutMs: 2_000 });
console.log({ health: health.status, ready: ready.status, components: ready.components });HealthResult health = admin.healthz();
HealthResult ready = admin.readyz();
System.out.println(health.status() + " " + ready.status());Expected healthy output is structurally similar to ok ready; component names and unknown future statuses must be preserved rather than coerced to success.
Quota and usage
Read current usage before changing a quota. Admin mutations support dry-run where the server contract permits it.
usage, err := admin.GetUsage(ctx, "acme")
quota, plan, err := admin.SetQuota(ctx, "acme", lockwelladmin.SetQuotaInput{
Bytes: 100 << 30, DryRun: true,
})
fmt.Println(usage.Bytes, quota, plan)const usage = await admin.getUsage("acme");
const plan = await admin.setQuota("acme", 100 * 1024 ** 3, { dryRun: true });
console.log({ used: usage.bytes, plan });var usage = admin.getUsage("acme");
var plan = admin.setQuotaDryRun("acme", 100L << 30);
System.out.println(usage + " " + plan);A quota denial is HTTP 507 with machine code quota_exceeded; it is not retryable. Catch the typed native/admin error, record its request id, and surface a capacity action rather than retrying the same write.
Key rotation
Created and rotated access-key secrets are returned once. Persist the new secret before switching callers, verify a request with the new key, then revoke the old key with an audit reason. listKeys never returns secrets. Use dry-run for supported mutation planning and never print a secret in ordinary logs or expected-output examples.
Audit and webhook correlation
Use the success metadata callback and typed error request id to correlate an application operation with queryAudit. Webhook notifications carry their own signed delivery; retain the signing secret only from the create response, because later reads expose hasSecret but not the secret. Verify the raw request bytes before JSON parsing.
Denial example
All clients preserve machine-readable failures. A retention-blocked delete should look like this at the application boundary (values are illustrative):
status=412 code=retention_blocked request_id=req_... action=wait_until_retention_expiresDo not retry 401, 403, 409 idempotency conflict, 412 retention/legal-hold/conditional failures, or 507 quota failures without changing the underlying condition.
Admin boundaries
Admin clients cover tenant, account, key, quota, usage, and audit workflows. Encryption-key rewrap, lifecycle/repair, placement, backup/restore, and daemon configuration remain CLI or authenticated admin-Web-UI workflows; the SDKs do not invent proposal-only methods for them.