Models
Certify S46 models, publish registry releases, and manage each team's allow-list.
Certify S46 models, publish registry releases, and manage each team's allow-list. Policy set here is what the harness gateway enforces at call time.
Route inventory
| Method | Route | Purpose |
|---|---|---|
GET | /v1/admin/model-releases | List API-backed model releases. |
POST | /v1/admin/model-releases | Create a model release. |
GET | /v1/admin/model-releases/{releaseId} | Read release state and evidence. |
POST | /v1/admin/model-releases/{releaseId}/upload-session | Open a quarantine upload session. |
POST | /v1/admin/model-releases/{releaseId}/finalize-upload | Finalize artifact metadata into quarantine CAS. |
POST | /v1/admin/model-releases/{releaseId}/validate | Queue S46 certification worker validation. |
POST | /v1/admin/model-releases/{releaseId}/publish | Queue the registry publisher. |
POST | /v1/admin/model-releases/{releaseId}/yank | Block serving and queue a signed yank. |
GET | /v1/admin/models | List certified models the org may allow. |
GET | /v1/admin/model-policies?team={team} | Read a team's allow-list and default model. |
PUT | /v1/admin/model-policies?team={team} | Set a team's allow-list and default model. |
Model release lifecycle
The API creates release records and queues model-worker jobs; it does not treat an uploaded artifact as certified until a certification worker reports green evidence with threshold signatures.
POST /v1/admin/model-releasescreatesstagedstate for{ namespace, team, modelSlug }.POST /v1/admin/model-releases/{releaseId}/upload-sessionreturns aPUTupload URL for the expected SHA-256 and size.POST /v1/admin/model-releases/{releaseId}/finalize-uploadrecords quarantine CAS metadata underS46_MODEL_QUARANTINE_URI.POST /v1/admin/model-releases/{releaseId}/validatequeues amodel.certifyjob for workers withmodel_certification.- Worker completion stores green verification evidence, private-holdout suite metadata, threshold-signing records, and Sigsum status.
POST /v1/admin/model-releases/{releaseId}/publishqueuesmodel.publishfor workers withmodel_registry_publish; the publisher writes content-addressed artifacts and flips the signed registry index.POST /v1/admin/model-releases/{releaseId}/yanksetsservingBlocked=trueimmediately, updates the local catalog mirror to fail closed, and queuesmodel.yankfor signed advisory/yank publication.
All mutating release actions after create require If-Match; retryable actions also require Idempotency-Key.
curl -X POST https://api.s46.dev/v1/admin/model-releases \
-H "Authorization: Bearer $S46_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"namespace":"s46","team":"@s46/engineering","modelSlug":"devstral-small-2-24b"}'{
"id": "rel_...",
"namespace": "s46",
"teamSlug": "@s46/engineering",
"modelId": "s46/devstral-small-2-24b",
"version": "r000001",
"state": "staged",
"revision": 1,
"etag": "\"1\""
}Certified models
The certified catalog is still the serving gate. Each model must be certified, published, trusted, and not globally blocked by advisory/yank state before the gateway can serve it.
curl https://api.s46.dev/v1/admin/models \
-H "Authorization: Bearer $S46_ACCESS_TOKEN"{
"models": [
{
"id": "s46/devstral-small-2-24b",
"displayName": "s46/devstral-small-2-24b",
"provider": "s46",
"certified": true,
"published": true,
"verificationState": "trusted",
"sigsumStatus": "verified"
}
]
}Team model policy
A team's policy determines which certified models the gateway will serve for that team. A request for a model outside the allow-list fails at the gateway with 403 model_not_allowed.
curl "https://api.s46.dev/v1/admin/model-policies?team=%40s46%2Fengineering" \
-H "Authorization: Bearer $S46_ACCESS_TOKEN"
curl -X PUT "https://api.s46.dev/v1/admin/model-policies" \
-H "Authorization: Bearer $S46_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: policy-$(uuidgen)" \
-d '{"team":"@s46/engineering","modelId":"s46/devstral-small-2-24b","allowed":true}'{
"team": "@s46/engineering",
"modelId": "s46/devstral-small-2-24b",
"allowed": true,
"revision": 1,
"etag": "\"1\""
}