CapabilitySource tracks where a capability came from. This is useful for debugging, auditing, and understanding how permissions were granted.
Factory Methods
user
@staticmethod
CapabilitySource.user() -> CapabilitySource
Create a user-sourced capability. This is the default source when you call allow_path() or allow_file().
from nono_py import CapabilitySource
source = CapabilitySource.user()
print(source) # "user"
group
@staticmethod
CapabilitySource.group(name: str) -> CapabilitySource
Create a group-sourced capability. Used when permissions come from a named policy group.
Name of the policy group (e.g., "claude-code", "development").
source = CapabilitySource.group("claude-code")
print(source) # "group(claude-code)"
system
@staticmethod
CapabilitySource.system() -> CapabilitySource
Create a system-sourced capability. Used for paths required for basic system operation.
source = CapabilitySource.system()
print(source) # "system"
String Representation
from nono_py import CapabilitySource
print(str(CapabilitySource.user())) # "user"
print(str(CapabilitySource.group("mygroup"))) # "group(mygroup)"
print(str(CapabilitySource.system())) # "system"
print(repr(CapabilitySource.user())) # "CapabilitySource(user)"
Usage
The source is attached to each FsCapability and can be accessed via the source property:
from nono_py import CapabilitySet, AccessMode
caps = CapabilitySet()
caps.allow_path("/tmp", AccessMode.READ_WRITE)
for cap in caps.fs_capabilities():
print(f"{cap.resolved}: {cap.source}")
# /private/tmp: user
Source Priority
When deduplicating capabilities with CapabilitySet.deduplicate(), user-granted capabilities take priority over system-granted ones. This ensures user intent is preserved.