1use auths_core::error::AuthsErrorInfo;
2use thiserror::Error;
3
4#[derive(Debug, Error)]
16#[non_exhaustive]
17pub enum OrgError {
18 #[error("no admin with the given public key found in organization '{org}'")]
20 AdminNotFound {
21 org: String,
23 },
24
25 #[error("member '{did}' not found in organization '{org}'")]
27 MemberNotFound {
28 org: String,
30 did: String,
32 },
33
34 #[error("member '{did}' is already revoked")]
36 AlreadyRevoked {
37 did: String,
39 },
40
41 #[error("invalid capability '{cap}': {reason}")]
43 InvalidCapability {
44 cap: String,
46 reason: String,
48 },
49
50 #[error("invalid organization DID: {0}")]
52 InvalidDid(String),
53
54 #[error("invalid public key: {0}")]
56 InvalidPublicKey(String),
57
58 #[error("signing error: {0}")]
60 Signing(String),
61
62 #[error("identity error: {0}")]
64 Identity(String),
65
66 #[error("key storage error: {0}")]
68 KeyStorage(String),
69
70 #[error("storage error: {0}")]
72 Storage(#[source] auths_id::storage::registry::backend::RegistryError),
73
74 #[error("anchor error: {0}")]
76 Anchor(#[from] auths_id::keri::AnchorError),
77
78 #[error(
82 "organization '{org}' uses a multi-signature controller (kt≥2); KERI-native member delegation requires a single-signature (kt=1) org"
83 )]
84 OrgThresholdDelegationUnsupported {
85 org: String,
87 },
88
89 #[error("a member key already exists under alias '{alias}'")]
92 MemberKeyExists {
93 alias: String,
95 },
96
97 #[error("member '{did}' is not a delegated identifier of organization '{org}'")]
101 MemberNotDelegable {
102 did: String,
104 org: String,
106 },
107
108 #[error("crypto error: {0}")]
110 CryptoError(#[source] auths_core::AgentError),
111
112 #[error("member delegation failed: {0}")]
114 Delegation(#[source] auths_id::error::InitError),
115
116 #[error("an identity already exists at {location}; refusing to create an organization over it")]
119 IdentityExists {
120 location: String,
122 },
123
124 #[error("failed to initialize organization identity: {0}")]
126 IdentityInit(#[source] auths_id::error::InitError),
127
128 #[error("failed to create admin attestation: {0}")]
130 Attestation(#[source] auths_verifier::error::AttestationError),
131
132 #[error("bundle integrity failure for '{id}': {reason}")]
135 BundleIntegrity {
136 id: String,
138 reason: String,
140 },
141
142 #[error("bundle is missing the KEL for delegated member '{member}'")]
145 BundleMissingMemberKel {
146 member: String,
148 },
149
150 #[error("member '{member}' has no delegation seal in the org KEL")]
153 BundleMissingDelegatorSeal {
154 member: String,
156 },
157
158 #[error("invalid org policy: {reason}")]
162 PolicyCompile {
163 reason: String,
165 },
166
167 #[error("org policy blob for hash '{hash}' is missing from storage")]
170 PolicyBlobMissing {
171 hash: String,
173 },
174
175 #[error(
178 "org policy integrity failure: KEL committed hash '{expected}' but the stored blob hashes to '{actual}'"
179 )]
180 PolicyIntegrity {
181 expected: String,
183 actual: String,
185 },
186
187 #[error("delegation chain cycle detected at '{did}'")]
190 ChainCycle {
191 did: String,
193 },
194
195 #[error("delegation chain exceeds the maximum depth of {max} hops")]
197 ChainTooDeep {
198 max: u32,
200 },
201
202 #[error("delegation chain is broken: no KEL found for '{did}'")]
205 ChainBrokenHop {
206 did: String,
208 },
209}
210
211impl AuthsErrorInfo for OrgError {
212 fn error_code(&self) -> &'static str {
213 match self {
214 Self::AdminNotFound { .. } => "AUTHS-E5601",
215 Self::MemberNotFound { .. } => "AUTHS-E5602",
216 Self::AlreadyRevoked { .. } => "AUTHS-E5603",
217 Self::InvalidCapability { .. } => "AUTHS-E5604",
218 Self::InvalidDid(_) => "AUTHS-E5605",
219 Self::InvalidPublicKey(_) => "AUTHS-E5606",
220 Self::Signing(_) => "AUTHS-E5607",
221 Self::Identity(_) => "AUTHS-E5608",
222 Self::KeyStorage(_) => "AUTHS-E5609",
223 Self::Storage(_) => "AUTHS-E5610",
224 Self::Anchor(_) => "AUTHS-E5611",
225 Self::OrgThresholdDelegationUnsupported { .. } => "AUTHS-E5612",
226 Self::MemberKeyExists { .. } => "AUTHS-E5613",
227 Self::MemberNotDelegable { .. } => "AUTHS-E5618",
228 Self::CryptoError(e) => e.error_code(),
229 Self::Delegation(_) => "AUTHS-E5614",
230 Self::IdentityExists { .. } => "AUTHS-E5615",
231 Self::IdentityInit(_) => "AUTHS-E5616",
232 Self::Attestation(_) => "AUTHS-E5617",
233 Self::BundleIntegrity { .. } => "AUTHS-E5619",
234 Self::BundleMissingMemberKel { .. } => "AUTHS-E5620",
235 Self::BundleMissingDelegatorSeal { .. } => "AUTHS-E5621",
236 Self::PolicyCompile { .. } => "AUTHS-E5622",
237 Self::PolicyBlobMissing { .. } => "AUTHS-E5623",
238 Self::PolicyIntegrity { .. } => "AUTHS-E5624",
239 Self::ChainCycle { .. } => "AUTHS-E5625",
240 Self::ChainTooDeep { .. } => "AUTHS-E5626",
241 Self::ChainBrokenHop { .. } => "AUTHS-E5627",
242 }
243 }
244
245 fn suggestion(&self) -> Option<&'static str> {
246 match self {
247 Self::AdminNotFound { .. } => {
248 Some("Verify you are using the correct admin key for this organization")
249 }
250 Self::MemberNotFound { .. } => {
251 Some("Run `auths org list-members` to see current members")
252 }
253 Self::AlreadyRevoked { .. } => {
254 Some("This member has already been revoked from the organization")
255 }
256 Self::InvalidCapability { .. } => {
257 Some("Use a valid capability (e.g., 'sign_commit', 'manage_members', 'admin')")
258 }
259 Self::InvalidDid(_) => Some("Organization DIDs must be valid did:keri identifiers"),
260 Self::InvalidPublicKey(_) => Some("Public keys must be hex-encoded Ed25519 keys"),
261 Self::Signing(_) => {
262 Some("The signing operation failed; check your key access with `auths key list`")
263 }
264 Self::Identity(_) => {
265 Some("Failed to load identity; run `auths id show` to check identity status")
266 }
267 Self::KeyStorage(_) => {
268 Some("Failed to access key storage; run `auths doctor` to diagnose")
269 }
270 Self::Storage(_) => {
271 Some("Failed to access organization storage; check repository permissions")
272 }
273 Self::Anchor(_) => Some("KEL anchoring failed; check identity and registry state"),
274 Self::OrgThresholdDelegationUnsupported { .. } => Some(
275 "Multi-signature org anchoring is not yet supported; use a single-signature (kt=1) org",
276 ),
277 Self::MemberKeyExists { .. } => Some(
278 "Choose a different member alias; run `auths org list-members` to see existing members",
279 ),
280 Self::MemberNotDelegable { .. } => Some(
281 "The member must first incept a delegated identity naming this org as delegator (pairing) before it can be off-boarded",
282 ),
283 Self::CryptoError(e) => e.suggestion(),
284 Self::Delegation(_) => Some(
285 "The member delegation could not be authored or anchored; check the org identity",
286 ),
287 Self::IdentityExists { .. } => Some(
288 "An identity already exists here; use a fresh repository path to create a new organization",
289 ),
290 Self::IdentityInit(_) => {
291 Some("Failed to initialize the org identity; check key access and repository state")
292 }
293 Self::Attestation(_) => Some(
294 "Failed to sign the admin attestation; check your key access with `auths key list`",
295 ),
296 Self::BundleIntegrity { .. } => Some(
297 "The bundle was modified after it was produced; obtain a fresh, untampered bundle",
298 ),
299 Self::BundleMissingMemberKel { .. } | Self::BundleMissingDelegatorSeal { .. } => {
300 Some("The bundle is incomplete; re-produce it with `auths org bundle`")
301 }
302 Self::PolicyCompile { .. } => Some(
303 "Fix the policy JSON (a serialized `Expr`); see `auths org policy show` for the current policy",
304 ),
305 Self::PolicyBlobMissing { .. } => {
306 Some("The policy blob is missing; re-anchor it with `auths org policy set`")
307 }
308 Self::PolicyIntegrity { .. } => Some(
309 "The stored policy was modified after anchoring; re-anchor a trusted policy with `auths org policy set`",
310 ),
311 Self::ChainCycle { .. } => {
312 Some("The delegation chain is malformed (a cycle); inspect the identifiers' KELs")
313 }
314 Self::ChainTooDeep { .. } => {
315 Some("The delegation chain is too deep; reduce delegation nesting")
316 }
317 Self::ChainBrokenHop { .. } => Some(
318 "A KEL in the delegation chain is missing; ensure all delegators' KELs are present",
319 ),
320 }
321 }
322}