Introduction
A badge is a resource that a component accepts as proof of authority. Radix Engine defines no badge type and no badge opcode. What makes a resource a badge is that an access rule somewhere names it.
The working distinction is between holding and showing. To move XRD you put it in a bucket and hand the bucket over, and the balance leaves your account. To use a badge you create a proof of it, and the proof is a claim about what a vault contains that the engine checks and then discards. The badge stays where it was. A door pass works the same way: the guard reads it, and you keep it.
Because the thing being shown is an ordinary resource, everything the ledger already guarantees about resources applies to authority too. A badge cannot be copied, cannot be conjured by the component that demands it, and cannot go missing without someone having moved it.
Showing, not spending
Every transaction runs with an auth zone, a scratch space holding the proofs presented so far. A transaction manifest creates a proof from a vault, pushes it into the auth zone, and calls a method. The engine then tests that method’s access rule against whatever the auth zone is carrying at that moment.
The rule is a small expression over resource addresses. require names a single badge. require_amount demands a quantity of a fungible one, which is how a component charges for a privilege rather than gating it. require_any_of and require_all_of compose those into m-of-n conditions. The operand is always a resource address, so any resource can gate any method, and one badge can gate methods on components written years apart by people who never spoke.
A proof is scoped to the transaction that made it. It cannot be stored in component state, returned to a caller as a durable capability, or replayed in a later transaction. When the transaction finalizes, the auth zone is emptied. That scoping is what lets an access rule be written as a question about the present moment rather than a ledger of who was granted what.
Badges nobody holds
Some badges have no holders and never will. The engine mints proofs of them from facts it already knows about the transaction, and the resource exists to give those facts an address that an access rule can name.
The signature badge is the clearest case. Radix has one per curve: the EdDSA Ed25519 Signature Resource at resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg, and the ECDSA Secp256k1 Signature Resource at resource_rdx1nfxxxxxxxxxxsecpsgxxxxxxxxx004638826440xxxxxxxxxsecpsg. Both read the same way on-ledger: total supply zero, minter deny_all, burner deny_all, and every authority locked against future change. Nobody holds one, and no one can ever issue one.
They are presented constantly. When a transaction is signed, the engine derives a non-fungible id from the hash of the signing public key and places a proof of that id into the auth zone. An account component’s default rule requires exactly that badge, which is how a signature becomes an authorization without the account ever storing a key. The resource is a name for a property of the transaction, and zero supply is the honest expression of that.
The same construction answers a different question for code. The Package of Direct Caller Resource, at resource_rdx1nfxxxxxxxxxxpkcllrxxxxxxxxx003652646977xxxxxxxxxpkcllr, is also supply zero and also unmintable, and a proof of it identifies the package whose code made the current call. A component can therefore admit calls from one specific body of code and refuse every other caller, human or otherwise.
The badges the system issues
Against those, the badges the system actually hands out have supply, holders, and a mint rule worth reading. Account Owner Badges live at resource_rdx1nfxxxxxxxxxxaccwnrxxxxxxxxx006664022062xxxxxxxxxaccwnr and stood at 761 in supply at epoch 339,016. One is issued when an account is created with an owner badge, and holding it grants control over that account component.
Its minter rule is the interesting part. Minting is protected, and the badge it requires is a single specific non-fungible of the Package of Direct Caller Resource described above – the id naming the account package itself. Only the account package’s own code can mint an account owner badge, and that restriction is locked against amendment.
Badges gate badges, in other words, and the recursion bottoms out in the implicit resources the engine controls rather than in a privileged administrator. The same shape governs the owner badges issued for packages, validators and identities.
What the pattern costs
A badge is a bearer instrument. Whoever holds it has the authority, and a component asked to verify one has no way to distinguish its intended holder from a thief. Losing the badge loses the privilege, permanently, unless recovery was designed in beforehand – which is the problem the Access Controller exists to solve.
Transferability is the same trade seen from the other side. Because badges are resources, they move like resources, so authority is transferable by default. A badge meant to stay put has to be made non-transferable at creation by denying its withdrawer role, and that choice cannot be walked back once the rules are locked.
Babylon formalized the arrangement rather than replacing it. The role assignment module gives every component a set of named roles, each mapped to an access rule, so a blueprint declares who may do what once and the badges satisfying those roles can be rotated underneath. The badge remains the credential; the role is the slot it fits.
What the pattern buys is a single vocabulary. Permissions on Radix are not a parallel system bolted beside the asset model – they are expressed in it, using the same asset-oriented primitives as tokens, and inheriting the same guarantees against duplication and silent loss.
