A beginner-friendly guide to understanding capabilities in software: what they are, why they matter, and how they help control what code is allowed to do.
A capability is a specific power.
If code has the capability, it can do the thing.
If it does not, it cannot.
Table of Contents
- The Simple Idea
- Why Capabilities Exist
- Permission vs Capability
- Capability As A Handle
- Capabilities In Runtimes
- Why This Matters For Untrusted Code
- My Learning Notes
- Common Misunderstandings
The Simple Idea
A capability is permission plus access.
It is not just:
you are allowedIt is more like:
here is the specific tool you may useExample:
read this file
send this HTTP request
query this database
render this template
write this responseThe code can only do what the host gives it the ability to do.
Why Capabilities Exist
Software often runs code that should not have unlimited power.
Examples:
- plugins,
- scripts,
- tenants,
- user-defined logic,
- serverless functions,
- workflow steps,
- browser extensions,
- sandboxed modules.
If that code can access everything, the system is fragile.
Capabilities make access explicit.
Permission vs Capability
Permission is often a rule.
Capability is often the actual handle.
Permission:
this script is allowed to read imagesCapability:
this script receives an image reader objectThe difference matters.
If code never receives the handle, it cannot use the power.
Capability As A Handle
Think of a capability like a key.
If you have the key, you can open the door.
If you do not have the key, knowing the door exists is not enough.
In software:
no database handle
no database queryno network function
no network requestThe host controls which keys are handed out.
Capabilities In Runtimes
A runtime can expose capabilities through APIs.
For example:
envfor environment values,dbfor database access,httpfor outbound requests,renderfor templates,responsefor output,filefor controlled file access.
The important part is that these are not ambient powers.
They are provided by the host.
Why This Matters For Untrusted Code
If a runtime executes code from many tenants, plugins, or users, capability design becomes critical.
The question is not only:
can this code run?The question is:
what can this code reach while it runs?A capability model helps keep the answer small and explicit.
KitJS And Kitwork Notes
Capability became clearer to me after moving from small browser behavior to a server runtime. KitJS mainly needs narrow browser powers: read an element, update text, listen to an event, bind an input. Kitwork has to think about a larger world: environment values, templates, files, database access, HTTP calls, and tenant boundaries.
That shift changed the question from "can the code run?" to "what power does the runtime hand to this code while it runs?"
My Learning Notes
I used to think about runtime mostly as execution.
Capabilities changed that.
When code runs inside a host, the host must decide what powers are visible.
In Kitwork, this idea appears when tenant logic receives controlled APIs instead of direct access to the whole machine.
That changed the mental model:
runtime is not only where code runs
runtime is where authority is handed outThe lesson:
capability is power made explicitCommon Misunderstandings
"Capability means role."
Not exactly. A role may decide what capabilities are granted, but a capability is the specific power or handle.
"If code is trusted, capabilities do not matter."
They still help architecture. Explicit access is easier to reason about than ambient access.
"Capabilities are only for security systems."
Security is one use. Capabilities also make systems clearer and easier to test.
Related Concepts
Previous: scope
Next: grant