Core Concepts

Scopes

How Spineforge ensures each agent can only do what it was authorized to do.


Declaring scopes at registration

Scopes are declared when your agent calls spineforge.init():

spine = spineforge.init(
    agent_name="research-agent",
    allowed_scopes=[
        "telemetry:write",    # Write runs/actions to the backend
        "credential:lease",   # Lease provider credentials
        "tools:web_search",   # Custom scope for your tool logic
    ]
)

These scopes are sent to the registry at registration time and stored alongside the agent's public key. They define the ceiling of what the agent can ever request — no runtime escalation is possible.

Requesting a token with scopes

# Request a token for a specific scope subset
token = spine.request_token(
    scopes=["tools:web_search"],
    aud="registry"    # or another agent's Spine ID
)

The requested scopes must be a subset of the agent's declared allowed_scopes. If any requested scope is not in the declared set, the request fails with a scope error — no partial grants.

JWT claims structure

// Decoded JWT payload
{
  "sub":   "spine_a1b2c3d4",             // Agent's Spine ID
  "aud":   "registry",                   // Or target agent Spine ID
  "scope": "telemetry:write tools:web_search",
  "iat":   1735689600,                   // Issued at (Unix timestamp)
  "exp":   1735693200                    // Expires at (short-lived)
}

Scope enforcement — set membership

Validation is pure set membership. The registry checks:requested_scopes ⊆ allowed_scopes

There is no partial grant. If you request ["credential:lease", "tools:admin"] and tools:admin is not declared, the entire request is rejected — you don't get credential:lease either.

Agent-to-agent delegation

An agent can delegate to another agent by setting aud to the target agent's Spine ID:

# Orchestrator agent delegating to a worker agent
delegation_token = spine.request_token(
    scopes=["tools:web_search"],
    aud="spine_worker_xyz"    # Target agent's Spine ID
)

# Pass this token to the worker agent

The receiving agent verifies the token locally against the registry's JWKS endpoint (cached). No Spineforge roundtrip is needed on the receive side — verification is pure cryptography.

Verifying a token (Receiving Agent)

When your agent receives a token from another agent (or from an external system), you use the SDK to verify it and check if it contains the required scope.

# Inside the receiving agent (e.g. the Finance Agent)
def handle_refund_request(token, amount):
    # This will throw an error if the token is invalid, expired, 
    # or does NOT contain the 'tools:refund' scope.
    claims = spineforge.verify_token(token, required_scope="tools:refund")
    
    print(f"Authorized! Request came from: {claims['sub']}")
    # Process refund...

Built-in scopes

ScopeWhat it grants
telemetry:writeWrite runs and actions to the Spineforge backend
credential:leaseLease provider credentials via /credentials/lease
agent:readRead other agents' metadata from the registry

Custom scopes (e.g. tools:web_search) can be declared freely — Spineforge treats them as opaque strings and enforces set membership.

Next steps