Access Control
HDDS implements fine-grained access control for topics and domains.
Overview
Access control defines:
- Which participants can join which domains
- Which topics a participant can publish to
- Which topics a participant can subscribe to
- Which partitions are accessible
Configuration Files
Governance
Domain-wide security policies:
<?xml version="1.0" encoding="UTF-8"?>
<governance>
<domain_rule>
<domains><id>0</id></domains>
<allow_unauthenticated_participants>false</allow_unauthenticated_participants>
<enable_discovery_protection>true</enable_discovery_protection>
<enable_liveliness_protection>true</enable_liveliness_protection>
<topic_rule>
<topic_expression>*</topic_expression>
<enable_encryption>true</enable_encryption>
</topic_rule>
</domain_rule>
</governance>
Permissions
Per-participant access rules:
<?xml version="1.0" encoding="UTF-8"?>
<permissions>
<grant name="SensorNode">
<subject_name>CN=SensorNode1</subject_name>
<validity>
<not_before>2024-01-01T00:00:00</not_before>
<not_after>2025-12-31T23:59:59</not_after>
</validity>
<allow_rule>
<domains><id>0</id></domains>
<publish>
<topics><topic>sensor/*</topic></topics>
</publish>
<subscribe>
<topics><topic>command/*</topic></topics>
</subscribe>
</allow_rule>
<deny_rule>
<domains><id>0</id></domains>
<publish>
<topics><topic>admin/*</topic></topics>
</publish>
</deny_rule>
</grant>
</permissions>
Grant Structure
<grant name="GrantName">
<!-- X.509 Common Name to match -->
<subject_name>CN=ParticipantName</subject_name>
<!-- Validity period -->
<validity>
<not_before>2024-01-01T00:00:00</not_before>
<not_after>2025-12-31T23:59:59</not_after>
</validity>
<!-- Allow rules (evaluated first) -->
<allow_rule>...</allow_rule>
<!-- Deny rules (take precedence) -->
<deny_rule>...</deny_rule>
</grant>
Rule Matching
Topic Wildcards
| Pattern | Matches | Does Not Match |
|---|---|---|
* | Any topic | - |
sensor/* | sensor/temp, sensor/humidity | command/start |
*/status | robot/status, sensor/status | robot/command |
*temp* | temperature, sensor/temp | humidity |
Domain Matching
<!-- Single domain -->
<domains><id>0</id></domains>
<!-- Multiple domains -->
<domains>
<id>0</id>
<id>1</id>
<id>2</id>
</domains>
<!-- Domain range -->
<domains>
<id_range><min>0</min><max>10</max></id_range>
</domains>
Partition Matching
<allow_rule>
<domains><id>0</id></domains>
<publish>
<topics><topic>sensor/*</topic></topics>
<partitions>
<partition>production</partition>
<partition>test</partition>
</partitions>
</publish>
</allow_rule>
Rule Precedence
- Deny rules are checked first - explicit deny always wins
- Allow rules are checked second - must have explicit allow
- Default deny - if no rule matches, access is denied
<!-- Deny admin topics to everyone except admin role -->
<deny_rule>
<domains><id>0</id></domains>
<publish>
<topics><topic>admin/*</topic></topics>
</publish>
</deny_rule>
<allow_rule>
<domains><id>0</id></domains>
<publish>
<topics><topic>*</topic></topics>
</publish>
</allow_rule>
Configuration in HDDS
use hdds::prelude::*;
use hdds::security::SecurityConfig;
let security = SecurityConfig::builder()
.identity_certificate("certs/participant.pem")
.private_key("certs/participant_key.pem")
.ca_certificates("certs/ca.pem")
.permissions_xml("permissions.xml") // Access control rules
.build()?;
Access Check Points
HDDS checks permissions at these points:
| Operation | Check |
|---|---|
| Join domain | Domain ID in grant |
| Create DataWriter | Publish permission for topic |
| Create DataReader | Subscribe permission for topic |
| Match remote writer | Subscribe permission |
| Match remote reader | Publish permission |
Example Configurations
Sensor Node (Publish Only)
<grant name="SensorNode">
<subject_name>CN=Sensor*</subject_name>
<validity>
<not_before>2024-01-01T00:00:00</not_before>
<not_after>2025-12-31T23:59:59</not_after>
</validity>
<allow_rule>
<domains><id>0</id></domains>
<publish>
<topics><topic>sensor/*</topic></topics>
</publish>
</allow_rule>
</grant>
Controller (Full Access)
<grant name="Controller">
<subject_name>CN=MainController</subject_name>
<validity>
<not_before>2024-01-01T00:00:00</not_before>
<not_after>2025-12-31T23:59:59</not_after>
</validity>
<allow_rule>
<domains><id>0</id></domains>
<publish>
<topics><topic>*</topic></topics>
</publish>
<subscribe>
<topics><topic>*</topic></topics>
</subscribe>
</allow_rule>
</grant>
Monitor (Subscribe Only)
<grant name="Monitor">
<subject_name>CN=Monitor*</subject_name>
<validity>
<not_before>2024-01-01T00:00:00</not_before>
<not_after>2025-12-31T23:59:59</not_after>
</validity>
<allow_rule>
<domains><id>0</id></domains>
<subscribe>
<topics><topic>*</topic></topics>
</subscribe>
</allow_rule>
<deny_rule>
<domains><id>0</id></domains>
<publish>
<topics><topic>*</topic></topics>
</publish>
</deny_rule>
</grant>
Validation Errors
| Error | Cause | Resolution |
|---|---|---|
PermissionsDenied | No matching allow rule | Add allow rule for topic |
SubjectMismatch | CN doesn't match grant | Check certificate subject |
ValidityExpired | Grant validity expired | Update not_after date |
DomainNotAllowed | Domain ID not in grant | Add domain to grant |
Audit Logging
Enable audit logging to track access decisions:
let security = SecurityConfig::builder()
// ...
.permissions_xml("permissions.xml")
.enable_audit_log(true)
.build()?;
Logged events:
- Access granted (with topic/domain)
- Access denied (with reason)
- Permission file parse errors
Best Practices
- Principle of least privilege: Only grant what's needed
- Use wildcards carefully: Be specific when possible
- Explicit deny for sensitive topics: Even if not allowed elsewhere
- Short validity periods: Rotate permissions regularly
- Audit logging: Enable in production
Troubleshooting
Access Denied
# Enable access control debug logging
export RUST_LOG=hdds::security::access=debug
Check:
- Certificate CN matches grant subject_name
- Topic pattern matches requested topic
- Domain ID is in grant
- Current time within validity period
Permissions File Not Loading
Validate XML syntax:
xmllint --noout permissions.xml
Next Steps
- Encryption - Data protection
- Authentication - Identity verification