pub struct Principal {
pub id: PrincipalId,
pub kind: PrincipalKind,
pub org_path: Vec<OrgId>,
}Expand description
Canonical actor identity. Carries id, kind, and org-tree position.
Thread the same Principal through every downstream audit-emitting
service instead of forking local newtypes.
org_path is root-to-self inclusive. Platform-internal actors outside
any org tree use org_path: vec![].
§Construction
Principal::human— for human / end-user identities. Accepts auuid::Uuidto prevent PII (emails, display names) from entering audit logs. Requires theuuidfeature.Principal::try_parse— parse a UUID string into aPrincipal. ReturnsPrincipalParseErrorfor non-UUID input. Requiresuuid.Principal::system— for autonomous or system actors. Infallible but no longerconstdue toVecinorg_path.
§Semantics
Identity-only. Principal carries no authorization semantics: it
names an actor, nothing more. JWT/OIDC parsing, scope checks, and
permission resolution all belong in caller layers.
Principals are not secrets — Debug is not redacted, to preserve
visibility in audit logs and tracing output.
§Examples
use api_bones::Principal;
use uuid::Uuid;
// Human principal — UUID only, no emails or display names
let id = Uuid::new_v4();
let alice = Principal::human(id);
assert_eq!(alice.as_str(), id.to_string().as_str());
// System principal
let rotation = Principal::system("billing.rotation-engine");
assert_eq!(rotation.as_str(), "billing.rotation-engine");Fields§
§id: PrincipalIdThe opaque principal identifier.
kind: PrincipalKindThe kind of actor this principal represents.
org_path: Vec<OrgId>Org path from root to the acting org (inclusive). Empty = platform scope.
Only present when the uuid feature is enabled.
Implementations§
Source§impl Principal
impl Principal
Sourcepub fn human(uuid: Uuid) -> Self
pub fn human(uuid: Uuid) -> Self
Construct a principal for a human actor from a uuid::Uuid.
This is the correct constructor for end-user / operator identities.
By requiring a Uuid the API prevents callers from accidentally
passing emails, display names, or other PII that would propagate into
audit logs and OTEL spans (see issue #204).
§Examples
use api_bones::Principal;
use uuid::Uuid;
let id = Uuid::new_v4();
let p = Principal::human(id);
assert_eq!(p.as_str(), id.to_string().as_str());Sourcepub fn try_parse(s: &str) -> Result<Self, PrincipalParseError>
pub fn try_parse(s: &str) -> Result<Self, PrincipalParseError>
Parse a UUID string into a Principal.
Accepts any UUID text form that uuid::Uuid::parse_str recognises
(hyphenated, simple, URN, braced). Returns PrincipalParseError for
anything else, including emails and empty strings.
§Errors
Returns PrincipalParseError when s is not a valid UUID string.
§Examples
use api_bones::Principal;
let p = Principal::try_parse("550e8400-e29b-41d4-a716-446655440000").unwrap();
assert_eq!(p.as_str(), "550e8400-e29b-41d4-a716-446655440000");
assert!(Principal::try_parse("alice@example.com").is_err());Sourcepub fn system(id: &'static str) -> Self
pub fn system(id: &'static str) -> Self
Construct a system principal from a &'static string.
Infallible but no longer const since org_path is a Vec.
§Examples
use api_bones::Principal;
let bootstrap = Principal::system("orders.bootstrap");
assert_eq!(bootstrap.as_str(), "orders.bootstrap");Sourcepub fn as_str(&self) -> &str
pub fn as_str(&self) -> &str
Borrow the principal as a &str.
§Examples
use api_bones::Principal;
assert_eq!(Principal::system("bob").as_str(), "bob");Sourcepub fn with_org_path(self, org_path: Vec<OrgId>) -> Self
pub fn with_org_path(self, org_path: Vec<OrgId>) -> Self
Set the org path on this principal (builder-style).
§Examples
use api_bones::{Principal, OrgId};
use uuid::Uuid;
let p = Principal::human(Uuid::nil())
.with_org_path(vec![OrgId::generate()]);
assert!(!p.org_path.is_empty());Sourcepub fn org_path_display(&self) -> String
pub fn org_path_display(&self) -> String
Returns the org ancestry path as a comma-separated UUID string.
Produces "" for platform-internal actors with no org affiliation,
and "<uuid1>,<uuid2>,..." (root-to-self) for org-scoped actors.
Intended for use as an OTEL span attribute value (enduser.org_path).
use api_bones::Principal;
let p = Principal::system("svc");
assert_eq!(p.org_path_display(), "");