Access Director Agent
The Access Director Agent distributes Access Control information (passwords) to all subscribed agents in the OCS instance. See the main article on Access Control, and the Agent Description below.
usage: agent.py [-h] [--config-file CONFIG_FILE]
Agent Options
- --config-file
AccessDirector config file.
Configuration File Examples
OCS Site Config
To configure the Access Director Agent we need to add an AccessDirector block to our ocs configuration file. Here is an example configuration block using all of the available arguments:
{'agent-class': 'AccessDirector',
'instance-id': 'access-dir',
'arguments': ['--config-file', '/config/access-director.yaml']}
Docker Compose
The Access Director Agent can also be run in a Docker container. An example docker-compose service configuration is shown here:
ocs-access-dir:
image: simonsobs/ocs:latest
hostname: ocs-docker
environment:
- LOGLEVEL=info
- INSTANCE_ID=access-dir
volumes:
- ${OCS_CONFIG_DIR}:/config:ro
Access Director Configuration File
The format is described below, but for a browsable schema see
ocs.access.AccessDirectorConfig.
Here is an example configuration file:
# Policy file for OCS Access Directory Agent
passwords_block_default_hashfunc: none
distrib_hashfunc: md5
passwords:
- default: true
password_4: 'superuserPassword!'
- agent_class: 'FakeDataAgent'
instance_id: '!faker4'
password_2: 'fake2ser'
- instance_id: 'faker4'
password_2: 'specialLevel2'
password_3: 'speciallevel3'
exclusive_access_blocks:
- name: "the-fakers"
password: "lockout-test"
grants:
- instance_id: "faker4"
lock_levels: [1,2,3]
cred_level: 1
- instance_id: "faker*,!faker4"
lock_levels: [3]
cred_level: 3
The passwords entry is a list of password assignment blocks, which
define passwords that should grant clients certain credential levels
on certain agents.
The syntax of the assignment blocks is described in
ocs.access.AccessPasswordItem.
Examples
Example 1 – set the level (1,2,3,4) passwords for all agents to (‘’, ‘special2’, ‘special3’, ‘superuser’):
passwords:
- default: true
password_1: ''
password_2: 'special2'
password_3: 'special3'
password_4: 'superuser'
Example 2 – like Example 1 except that any agent with the class “FakeDataAgent” will have level 2 password set to ‘fake2’:
passwords:
- default: true
password_1: ''
password_2: 'special2'
password_3: 'special3'
password_4: 'superuser'
- agent_class: FakeDataAgent
password_2: 'fake2'
Example 3 – like Example 2 except that the agent with
instance_id=danger4 will not be granted any special level 2 or 3
access passwords. To do this, it is necessary to negatively match on
instance_id – the default: true block can only apply to
everything:
passwords:
- default: true
password_1: ''
password_4: 'superuser'
- instance_id: '!danger4'
password_2: 'special2'
password_3: 'special3'
- agent_class: FakeDataAgent
instance_id: '!danger4'
password_2: 'fake2'
exclusive_access_blocks
The exclusive_access_blocks entry is a list of access grant
blocks. Each block must at least have a (unique) “name” entry, and a
list of GrantConfigItem. Each
GrantConfigItem targets some set of agent instances (using the
default / agent_class / instance_id keys in the same way that
ocs.access.AccessPasswordItem does). The cred_level
declares what level to give the grantee, on the targeted instances.
The lockout_levels is a list of Credential Levels to lock out,
during this grant.
The additional settings items are:
passwords_block_default_hashfunc: name of the hash function to assume for passwords provided in the “passwords” block. (Default: “none”, meaning they are in cleartext.)distrib_hashfunc: hashfunc to use, instead of cleartext, when distributing passwords to agents. (Does not affect passwords that were provided already hashed – those are distributed in hashed form, correctly annotated with the hashfunc declared for them.)
Description
The role of this Agent is to distribute Access Control information to Agent Instances and Clients in the OCS instance. In an OCS there will normally be zero or one instance of the Access Director (but it’s possible to set up multiple instances, and have different agents attuned to different Access Directors).
The agent configuration is provided through the Access Config File,
the path to which is a command-line parameter. The manager
process distributes access information to agents on a special feed
(...feeds.controls). The task reload_config may be used to
trigger a reload of the config file. If there are syntax errors in
the config file, this will normally cause the reload to be ignored and
the existing configuration to persist.
Two “special access points” are exposed by the Access Director. The
agent_poll method is used by agents to request an update of their
current access information; they will normally do this when they
connect or reconnect to crossbar.
The request_exclusive access point is used by clients that wish to
establish an Exclusive Access Lock. The client would provide the name
of the access block, and a password (if defined). The Agent then
returns to that client a randomly generated password that the client
can use to talk to all agents covered by the grant. Starting then,
and until the grant expires or is released, the Agent distributes
updated access information to all agents that reflects the new access
rules – i.e. special access levels, granted based on that password,
and also any lock-outs that are associated with the grant.
Agent API
- class ocs.agents.access_director.agent.AccessDirector(agent, config_file)[source]
Agent for distributing Access Control information to all Agents in a system.
- manager()[source]
Process - Update the main access control feed with new access information. This occurs in response to agent queries, or if new grants require updates to access.
The
session.dataencodes information about any active exclusive grants. The entry forgrantscontains a list of :class:<AccessGrant> entries. It looks like this:'grants': [ { "name": "fake-subsystem", "expire_at": 1771356419.8087718, "grantee": "test-grant.py", "rules": [ { "hashed_pass": { "hash": "md5", "value": "03ba0072e0d32376" }, "cred_level": 2, "scope_spec": { "default": false, "agent_class": "FakeDataAgent", "instance_id": null }, "lockout_id": "fake-subsystem", "lockout_owner": "test-grant.py", "lockout_levels": [ 2, 3 ] }, { "hashed_pass": { "hash": "md5", "value": "03ba0072e0d32376" }, "cred_level": 1, "scope_spec": { "default": true, "agent_class": null, "instance_id": null }, "lockout_id": "fake-subsystem", "lockout_owner": "test-grant.py", "lockout_levels": [ 3 ] } ] } ]
- agent_poll(instance_id, agent_class)[source]
Special access point. This is used for agents to request an announcement of their password rules on the control feed. The instance_id and agent_class arguments must both be specified (and not None). Returns True if arguments are sufficiently valid and request was slated; otherwise False.
- request_exclusive(grant_name=None, password=None, action=None, expire_at=None, grantee=None, strict=None)[source]
Special access point. Request, renew, or release an exclusive access grant.
- Parameters:
grant_name (str) – Name of the grant, to match an entry in the “grant-blocks” section of the config file.
password (str) – The password, to be checked against the password specified in the grant block of the config.
action (str) – One of “acquire”, “renew” or “release”.
expire_at (float) – Unix timestamp for the desired expiry time of the grant.
grantee (str) – A string representing the client that has requested the lock. When passed with “acquire”, it is stored for distribution to clients so they can explain who has locked them out.
strict (bool) – If True, reject all requests except acquire when a grant is inactive, renew when a grant is active, and release when a grant is active.
- Returns:
A dict with useful info.
On error, the dict has only an entry “error” with an error message in it.
On success, the returned dict has at least the items ‘grant_name’ (which matches the requested grant_name) and ‘message’; the ‘message’ is just “grant acquired” / “grant renewed” / “grant released”. It also has the ‘step’ at which this event took effect in the director.
Additionally, if the ‘action’ is ‘acquire’ or ‘renew’ then the dict will include an entry ‘expire_at’ with the unix timestamp that the grant will be cancelled automatically. This timestamp may be earlier (but not later) than the time requested with the expire_at parameter.
If the action is ‘acquire’, then the dict also has an entry ‘password’, containing the password client should use to access the exclusive access targets for the duration of the access grant.