ferrite.json is the deployment and authority contract for a Ferrite app. It
names what exists, which handles the function receives, and how public traffic
may reach it.
Complete shape
{
"services": [
{ "name": "shop-state", "primitive": "store" },
{ "name": "shop-jobs", "primitive": "queue" },
{ "name": "shop-requests", "primitive": "queue" },
{ "name": "shop-replies", "primitive": "queue" },
{ "name": "shop-assets", "primitive": "blob" }
],
"applications": [{
"name": "shop",
"artifact_key": "apps/shop@v1",
"artifact_sha256": "0000000000000000000000000000000000000000000000000000000000000000",
"bindings": [
{ "handle": "state", "kind": "store", "service": "shop-state" },
{ "handle": "jobs", "kind": "queue", "service": "shop-jobs" },
{ "handle": "requests", "kind": "queue", "service": "shop-requests" },
{ "handle": "replies", "kind": "queue", "service": "shop-replies" },
{ "handle": "assets", "kind": "blob", "service": "shop-assets" }
],
"routes": [
{ "prefix": "/api/", "binding": "requests", "kind": "api" },
{ "prefix": "/", "binding": "assets", "kind": "content", "key_prefix": "site/", "public": true }
],
"compute": { "memory_mb": 128, "cpu_percent": 50 }
}]
}
Services
Use store, log or named topics, queue, ape, and blob for durable
resources. Functions are the application entries under applications.
Bindings
The handle is the name your Rust code passes to AppContext. The kind and
service must match. Do not grant a resource because an app may need it later.
Routes
Choose api, content, ws, or stream. API routes can forward an explicit
request-header allowlist and enforce rate_limit_per_min. Put the narrowest
matching prefixes before broader routes.
Compute and egress
Admission checks compute bounds and declared outbound authority before the app
runs. Each egress handle contains exact public URL prefixes in destinations.
Validate
ferrite validate --json
ferrite check --json
validate checks spec statics. check also runs admission and Rust compilation.