VIP Authorization (Modular VOLTTRON)
VIP (VOLTTRON Interconnect Protocol) authorization in modular VOLTTRON provides fine-grained access control over what authenticated agents can do on the platform. Unlike monolithic VOLTTRON where authorization rules were embedded in agent code and auth.json, modular VOLTTRON separates authorization into a flexible, administrator-configurable system.
For authentication, see VIP Authentication.
Overview
In modular VOLTTRON, authorization:
Is separate from agent code - Agents don’t dictate which methods are protected
Is instance-specific - Different instances of the same agent can have different permissions
Uses a Unix-style model - Agents, groups, roles, and capabilities
Is flexible - Both RPC method calls and pub/sub topics can be protected
Is centrally managed - Platform administrators define all access policies
The authorization framework is defined in abstract classes located in volttron-core/types/auth/auth_service.py,
with concrete implementations in volttron-lib-auth/src/volttron/auth/authz_manager.py and
message-bus-specific handling in volttron-lib-zmq.
Authorization Rules Persistence
authorization rules of a specific instance of volttron is persisted in $VOLTTRON_HOME/authz.json. On first time start of a volttron instance a authz.json is created for all service agents. Everytime a agent is installed, in addition to creating authentication credentials, agents are also given default set of authorization and the entries are persisted in $VOLTTRON_HOME/authz.json
Authorization Model
Unix-Style Hierarchy
Modular VOLTTRON’s authorization follows a Unix-inspired hierarchy:
agents - Similar to Unix users. Represents an authenticated peer (installed agent or service agent or remote agent)
agent_groups - Similar to Unix groups. Collections of agents that share permissions
Roles - Named permission sets that can be assigned to agents or agent_groups
Capabilities - Specific permissions: - RPC capabilities: Allow calling specific methods on specific agent instance - Pub/Sub capabilities: Allow publishing/subscribing to specific topics
The hierarchy flows like this:
Agents
├── Direct RPC Capabilities
├── Direct Pub/Sub Capabilities
└── Assigned Roles
├── RPC Capabilities (from role)
└── Pub/Sub Capabilities (from role)
Agent groups
├── Member agents
└── Assigned Roles
├── RPC Capabilities (inherited by members)
└── Pub/Sub Capabilities (inherited by members)
Example Structure
Roles:
- "admin" → Full RPC + Pub/Sub access
- "config_manager" → Can call config-store methods
- "historian_reader" → Can query historian
Groups:
- "building_operators" → Agents: [op1, op2] → Roles: [config_manager]
- "technicians" → Agents: [tech1] → Roles: [historian_reader]
Agents: Identified by individual agent's vip id
- agent1.vipid → Groups: [building_operators] → Roles: [historian_reader]
- platform.historian → Direct rpc capabilities to call insert, query
RPC Method Authorization
RPC Authorization Overview
Protected RPC Methods
By default all RPC exported methods are open to call by vip.rpc.call by all agents. Unlike monolithic volttron, there is no restriction dictated at source code level. For example, in the below agent public_method and admin_method are both callable by rpc by all agent. But a volttron instance administrator can choose to protect one or more rpc methods by declaring it as “protected_rpcs” of a specific instance of the agent
class MyAgent(Agent):
@RPC.export
def public_method(self):
"""Any authenticated agent can call this."""
pass
@RPC.export
def admin_method(self):
"""This method is protected; only authorized agents can call it."""
For example, when I install two instance of the above agent say my-agent
vctl install --vip-identity myagent-instance1 my-agent
vctl install --vip-identity myagent-instance2 my-agent
The corresponding $VOLTTRON_HOME/authz.json entries would be
"myagent-instance1": {
"agent_roles": [
{
"default_rpc_capabilities": {
"identity": "myagent-instance1"
}
}
],
"comments": "Created during creation of credentials!"
},
"myagent-instance2": {
"agent_roles": [
{
"default_rpc_capabilities": {
"identity": "myagent-instance2"
}
}
],
"comments": "Created during creation of credentials!"
}
To make the admin_method restricted, administrator can edit the file to include “protected_rpcs” list, for example
"myagent-instance1": {
"protected_rpcs": ["admin_method"],
"agent_roles": [
{
"default_rpc_capabilities": {
"identity": "myagent-instance1"
}
}
],
"comments": "Created during creation of credentials!"
},
Or protect the method both instances you can add protected_rpcs entries to both ‘myagent-instance1’ and ‘myagent-instance2’
Granting RPC Permissions to protected methods
Platform administrators can grant RPC permissions to protected RPC methods by adding RPCCapabilities directly to agents, or agent groups or roles and then assigning the role to the agent
Method Naming Convention
RPCCapabilities specify the methods using the format:
<agent vip identity>.<method name>
For example:
platform.historian.query- The query method on the historian with vip id ‘platform.historian’platform.config_store.set_config- The set_config method on agent platform.config_storemy_agent.start_scan- The start_scan method on agent with vip id my_agent
This enables instance-specific authorization - you can protect platform.historian.query
without protecting backup_historian.query.
To grant access to say agent, calling-agent-1 to myagent-instance1's admin_method (see example in previous section)
edit the entry for caling-agent-1 in $VOLTTRON_HOME/authz.json to add “rpc_capabilities”
Example:
"calling-agent-1": {
"rpc_capabilities": [
"myagent-instance1.admin_method"
],
"protected_rpcs": ["calling_agent_protected_method1"],
"agent_roles": [
{
"default_rpc_capabilities": {
"identity": "calling-agent-1"
}
}
],
"comments": "Admin_agent1 added rpc capabilities"
},
Pub/Sub Authorization
Pub/Sub Overview
In modular VOLTTRON, pub/sub topics can be protected to control who can publish and subscribe. Unlike monolithic VOLTTRON (write-protection only), modular VOLTTRON supports both directions.
Topic Protection Patterns
Topics can be protected using:
Exact topic names:
building/hvac/temperatureRegular expressions: Expressions should be enclosed in forward slashes - example
/^building\/[^/]+\/temperature/,/.*/
Protected Topics
By default topics are not protected. To make a topic protected, add it to the list of protected topics in $VOLTTRON_HOME/authz.json This entry is not specific to a single agent. This is a single list for the entire instance -i.e all protected topics for this volttron instance. Hence authz entry should be made outside of any agent specific entry. The key “protected_topics” should be at the same level as “roles”, agents, and agent_groups
Pub/Sub Permissions
Once a pubsub topic is protected, only agents with explicit subscribe or publish capabilities can access it.
Authorized access rights includes:
publish: Permission to send messages on a topic
subscribe: Permission to receive messages on a topic
pubsub: Both publish and subscribe permissions
Excample: $VOLTTRON_HOME/authz.json entries for subscribe-only-agent and publish-only-agent
"subscribe-only-agent": {
"rpc_capabilities": [
"myagent-instance1.admin_method"
],
"protected_rpcs": ["subscribe_agents_protected_method1"],
"pubsub_capabilities": {
"devices/mysensitive-device": "subscribe"
},
"agent_roles": [
{
"default_rpc_capabilities": {
"identity": "subscribe-only-agent"
}
}
],
"comments": "Admin_agent1 added rpc capabilities, admin_agent2 added pubsub capabilities"
},
"publish-only-agent": {
"rpc_capabilities": [
"myagent-instance1.admin_method"
],
"protected_rpcs": ["my_protected_method2"],
"pubsub_capabilities": {
"devices/mysensitive-device": "publish"
},
"agent_roles": [
{
"default_rpc_capabilities": {
"identity": "subscribe-only-agent"
}
}
],
"comments": "Admin_agent1 added rpc capabilities, admin_agent2 added pubsub capabilities"
},
Working with Roles
Roles are named permission sets that encapsulate a collection of RPC and Pub/Sub capabilities. Roles simplify permission management by allowing you to define permissions once and assign the role to multiple agents or groups.
Benefits of Roles
Reusability: Define permissions once, apply to multiple agents and groups
Consistency: Ensure all members of a role have identical permissions
Maintainability: Update all role members by modifying the role definition
Scalability: Manage permissions at scale using role assignments
Creating and Managing Roles
Roles are defined in the $VOLTTRON_HOME/authz.json file under the “roles” section:
"roles": {
"historian_reader": {
"pubsub_capabilities": {
"historian/query": "subscribe",
"historian/results": "subscribe"
}
},
"config_manager": {
"rpc_capabilities": [
"platform.config_store.get_config",
"platform.config_store.set_config"
]
},
"admin": {
"rpc_capabilities": [
"/.*/"
],
"pubsub_capabilities": {
"/.*/": "pubsub"
}
}
}
Assigning Roles to Agents and Groups
Roles are assigned through the agent_roles property. An agent or group can have multiple roles.
Assigning to a single agent:
"my_agent": {
"agent_roles": ["historian_reader", "config_manager"]
}
Assigning role to a group: Example: assigning role to group operators
"agent_groups": {
"operators": {
"identities": ["operator1", "operator2"],
"agent_roles": [ "config_manager"]
}
}
Working with Groups
Groups enable managing permissions for multiple agents at once. To create an agent group, add a group under “agent_groups”
in $VOLTTRON_HOME/authz.json and add a list of agent identities to it. By default VOLTTRON creates an admin group that
can be used as an example
"agent_groups": {
"admin": {
"identities": [
"platform.federation",
"control.connection",
"platform.health",
"platform.control",
"platform",
"platform.config_store",
"platform.auth"
],
"agent_roles": [
"admin"
]
}
}
Best Practices
Use Roles for Common Permissions
Create roles for sets of capabilities that multiple agents or groups will need. This reduces duplication and makes it easier to maintain consistent permissions across your platform.
Use Groups for Collections of Agents
When multiple agents need the same permissions, use groups instead of assigning permissions individually.
Protect Sensitive Methods in Production Environments
Service agents’ sensitive methods are protected by default, but methods of any installed agent should be protected on a case-by-case basis. For example, in a production environment, a driver’s write methods that can write values to a device should be protected, and only trusted agents should have access to them
Use Topic Patterns Consistently
Use consistent naming schemes for topics to easily protect groups of related topics using patterns. For example:
building/<location>/<system>/<sensor> building/floor1/hvac/temperature building/floor1/lighting/status
Then protect groups of related topics using patterns.
Document Custom Roles
When creating roles, include comments in the authz.json explaining their purpose and intended use
Authorization vs. Authentication
Authentication answers: “Who are you?”
Proves identity via credentials (CURVE keys)
You cannot do anything without authenticating first
Handled by
ZMQServerAuthentication
Authorization answers: “What are you allowed to do?”
Controls access to RPC methods and pub/sub topics
Only applies after authentication succeeds
Handled by authorization managers and policies
Example Flow:
Agent connects with credentials
Authentication: Platform verifies credentials match (success → connection allowed)
Agent calls RPC method or publishes message
Authorization: Platform checks if agent has permission for that specific action
Action succeeds or fails based on permissions
Advanced Configuration
Role Inheritance
Roles can be assigned to groups, and groups can have multiple roles:
{
"roles": {
"reader": {
"pubsub_capabilities": {
"historian/query": "subscribe",
"historian/results": "subscribe"
}
},
"writer": {
"rpc_capabilities": [
"platform.historian.record"
]
}
},
"agent_groups": {
"data_managers": {
"identities": ["agent1", "agent2"],
"agent_roles": ["reader", "writer"]
}
}
}
Topic Wildcard Examples
# All HVAC topics in floor 1
"building/floor1/hvac/*"
# All topics in any building
"*/hvac/temperature"
# All topics (regex)
"/.*/
# Topics matching a complex pattern (regex)
"/building\\/([^/]+)\\/hvac\\/.*/ # building/*/hvac/...