Suppose your application has an API, a background worker, and a bucket for files. The API needs to read uploaded files. The worker does not.
Creating the bucket answers one question: what does this application need? Giving the API access answers another: which part of the application may use it? Fluffy records these decisions separately, so adding a resource never silently gives every runtime access to it.
#Understand resource access
A runtime is one of your running backend programs. A resource is something that program can use, such as a bucket or database. A grant connects a particular runtime to a resource and names the actions it may perform. Grants live under that runtime’s uses section.
For a bucket, access also has a prefix. A grant for uploads/ includes uploads/report.txt and excludes private/report.txt. These are object keys, not directories on the runtime’s filesystem.
Start with a bucket and an API that cannot read it. The green lines add one grant. Follow that change through SDK generation and deployment; the bucket itself already exists.
uses declares read access. Generation adds the API’s read methods; deployment connects its cloud identity to the bucket. These are separate operations, shown here as a short animation.#From a declaration to a running application
Editing the manifest changes the desired configuration. It does not rewrite generated files, change a running application, or send a request.
Generating the SDK creates code for a selected runtime. A bucket get grant adds Get and Stat operations to that runtime’s bucket client. Adding put also adds Put. The output includes Credential and Unwrap for provider access; those methods have provider-specific limits explained in the SDK guide.
Previewing deployment resolves the desired configuration into a proposed change. Deploying applies the reviewed infrastructure and application changes. The animation illustrates only access changes; a real deployment also builds images, prepares dependencies, and starts the new application version.
Calling the SDK is application behavior. Your program must actually call a generated operation before a request goes anywhere.
#What is allowed after this change?
| Request | Result |
|---|---|
API reads uploads/report.txt | Allowed by the grant |
API writes uploads/report.txt | No Put method in its read-only SDK |
API reads private/report.txt | Rejected by the object adapter: outside uploads/ |
| Worker reads the bucket | No bucket client: the API's grant does not belong to the worker |
The illustration assumes the object exists and the provider is healthy. Permission allows a request; it does not guarantee that a file exists or that the provider can complete it.
Adding put later creates another method when you regenerate. It becomes usable against the cloud only after deployment updates the runtime's access. Removing a grant follows the same sequence: update the code, regenerate, inspect the plan, and deploy. The bucket can remain throughout.
#Runtime permission and user permission
A runtime grant answers “may this backend read uploaded files?” It does not answer “may this signed-in person read this particular file?” Your handler must make that second decision before calling the SDK.
Browser code receives a different generated package. It can call explicitly exposed backend services and use configured authentication. It never receives a server-only bucket, database, or secret client. See Authentication for the complete browser-to-backend boundary.
#Configure a grant
In an existing application with an api runtime, declare a bucket and add its grant to fluffy-chainsaw.yaml:
buckets:
files: {}
runtimes:
api:
uses:
buckets:
- name: files
prefix: uploads/
actions: [get, put]This is an excerpt. Keep the runtime’s artifact and other existing fields, and add these entries to their corresponding mappings. The name files is local to this example; use your declared bucket’s name in a real application.
From your workspace root, generate the API’s Go package. Here the application is named example-app; substitute your application’s name:
fluffy-chainsaw generate --application example-app --runtime api --language typescriptThe generated package now contains a BucketsFiles client. Your Go code constructs it with NewBucketsFilesClient(connection). The SDK connection recipe explains connection; the storage guide shows complete streaming calls.
Run locally to exercise the change, or follow Deploy to GCP to preview and apply it in a configured environment. Generation requires the selected language tools. Cloud deployment additionally requires provider configuration and credentials.
#Remove access deliberately
Remove the bucket entry from the runtime’s uses.buckets, update code that used the client, and regenerate. Check the new deployment plan before applying it. Removing a grant is different from removing a bucket declaration, and generation alone does not revoke a running deployment’s access.
If another runtime still needs the bucket, keep its own grant. Runtime grants do not inherit from one another.
#Reference: supported grants and boundaries
Actions are specific to a resource kind. For example, bucket reads use get; secret reads use read. They are not interchangeable names for a universal permission.
| Resource kind under uses | Allowed actions | Main generated operations |
|---|---|---|
databases | read, write | GetConnection; SQL permissions follow the grant |
buckets | get, create, put, list, delete, delegateGet, delegateCreate, delegatePut | get adds Get and Stat; the other actions add the corresponding named operation |
secrets | read, list | ReadLatest, ReadVersion; ListVersions |
caches | get, set, delete | Get, Set, Delete |
topics, queues | produce | Publish |
auth | verify | Verify |
services | invoke | Call |
This table lists application operations. Resource clients also include native access methods where applicable; consult the generated SDK reference. Queue/topic receiving is declared through consumes, not an invented consume action under uses. Messaging covers receiving, acknowledgements, and push verification. Feature flags use uses.flags: true; extension capabilities have their own action catalogs.
#Rejected configuration
Fluffy rejects an unknown resource, duplicate resource edge within the same runtime/kind, empty action list, duplicate action, or unsupported action. Bucket grants must include a nonempty prefix. Giving one runtime two grants for the same bucket with different prefixes is still a duplicate edge.
#Checks at different boundaries
| Boundary | What it catches |
|---|---|
| Manifest validation | Invalid declarations, unresolved resources, duplicate edges, unsupported actions |
| SDK generation and typed application compilation | A target-specific client or method is absent when it has no grant |
| Source validation | Wrong-target or stale generated imports, provably unused grants, and unsupported dynamic usage patterns |
| Sidecar and provider adapter | Deployed contract, operation and resource scope, including bucket prefixes |
| Cloud provider | Effective provider identity permissions and resource availability |
| Application handler | Which user is allowed to perform the requested business operation |
The absence of a generated method is useful feedback, not the entire security boundary. A manually constructed request does not create a new deployed permission. Conversely, broad cloud permissions granted outside Fluffy are not erased by making an SDK smaller. Provider-native credentials have product-specific authority; use the portable methods unless you need native behavior and understand that provider’s scope.
Continue with Generated SDKs, or apply this model to storing files and connecting a database.