Cryptographic organizational credential for an AI agent. Issued by AgentIdentityService using Ed25519 keypairs signed by the Org CA. Not an API key. An AgentIdentity is: - Revocable at any time by org authority - Time-bounded (optional expiry) - Tied to a
| 60 | |
| 61 | |
| 62 | class AgentIdentity(BaseModel): |
| 63 | """ |
| 64 | Cryptographic organizational credential for an AI agent. |
| 65 | Issued by AgentIdentityService using Ed25519 keypairs signed by the Org CA. |
| 66 | |
| 67 | Not an API key. An AgentIdentity is: |
| 68 | - Revocable at any time by org authority |
| 69 | - Time-bounded (optional expiry) |
| 70 | - Tied to an organizational unit, not a developer account |
| 71 | - Cryptographically verifiable via public_key + org_ca_fingerprint |
| 72 | """ |
| 73 | model_config = {"frozen": True} |
| 74 | |
| 75 | agent_id: str = Field( |
| 76 | default_factory=_new_agent_id, |
| 77 | description="Globally unique agent identifier. Assigned at issuance.", |
| 78 | ) |
| 79 | agent_name: str = Field( |
| 80 | min_length=2, max_length=64, |
| 81 | description="Human-readable agent name, unique per org.", |
| 82 | ) |
| 83 | org_id: str = Field( |
| 84 | min_length=2, max_length=64, |
| 85 | description="Target organization identifier.", |
| 86 | ) |
| 87 | issued_by: str = Field( |
| 88 | min_length=1, max_length=64, |
| 89 | description="Organizational unit that authorized issuance.", |
| 90 | ) |
| 91 | public_key: str = Field( |
| 92 | description="Ed25519 public key in Base64url encoding. Private key never stored here.", |
| 93 | ) |
| 94 | org_ca_fingerprint: str = Field( |
| 95 | description="SHA-256 fingerprint of the Org CA that signed this identity.", |
| 96 | ) |
| 97 | issued_at: datetime = Field(default_factory=_now_utc) |
| 98 | valid_until: datetime | None = Field( |
| 99 | default=None, |
| 100 | description="UTC expiry timestamp. Null means no expiry — valid until explicitly revoked.", |
| 101 | ) |
| 102 | status: AgentIdentityStatus = Field(default=AgentIdentityStatus.ACTIVE) |
| 103 | revoked_at: datetime | None = None |
| 104 | revoked_by: str | None = None |
| 105 | revocation_reason: str | None = None |
| 106 | metadata: dict[str, str] = Field(default_factory=dict) |
| 107 | |
| 108 | @field_validator("agent_id") |
| 109 | @classmethod |
| 110 | def _validate_agent_id(cls, v: str) -> str: |
| 111 | if not _AGENT_ID_RE.match(v): |
| 112 | raise ValueError(f"agent_id '{v}' must match ^aid_[a-z0-9]+$") |
| 113 | return v |
| 114 | |
| 115 | @field_validator("agent_name") |
| 116 | @classmethod |
| 117 | def _validate_agent_name(cls, v: str) -> str: |
| 118 | if not _AGENT_NAME_RE.match(v): |
| 119 | raise ValueError(f"agent_name '{v}' must match ^[a-z][a-z0-9_-]*$") |
no outgoing calls
no test coverage detected