@auths-dev/sdk 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/Cargo.toml +45 -0
  2. package/README.md +163 -4
  3. package/__test__/client.spec.ts +78 -0
  4. package/__test__/exports.spec.ts +57 -0
  5. package/__test__/integration.spec.ts +407 -0
  6. package/__test__/policy.spec.ts +202 -0
  7. package/__test__/verify.spec.ts +88 -0
  8. package/build.rs +5 -0
  9. package/index.d.ts +259 -0
  10. package/index.js +622 -1
  11. package/lib/artifacts.ts +124 -0
  12. package/lib/attestations.ts +126 -0
  13. package/lib/audit.ts +189 -0
  14. package/lib/client.ts +293 -0
  15. package/lib/commits.ts +70 -0
  16. package/lib/devices.ts +178 -0
  17. package/lib/errors.ts +306 -0
  18. package/lib/identity.ts +280 -0
  19. package/lib/index.ts +125 -0
  20. package/lib/native.ts +255 -0
  21. package/lib/org.ts +235 -0
  22. package/lib/pairing.ts +271 -0
  23. package/lib/policy.ts +669 -0
  24. package/lib/signing.ts +204 -0
  25. package/lib/trust.ts +152 -0
  26. package/lib/types.ts +179 -0
  27. package/lib/verify.ts +241 -0
  28. package/lib/witness.ts +91 -0
  29. package/npm/darwin-arm64/README.md +3 -0
  30. package/npm/darwin-arm64/package.json +23 -0
  31. package/npm/linux-arm64-gnu/README.md +3 -0
  32. package/npm/linux-arm64-gnu/package.json +26 -0
  33. package/npm/linux-x64-gnu/README.md +3 -0
  34. package/npm/linux-x64-gnu/package.json +26 -0
  35. package/npm/win32-arm64-msvc/README.md +3 -0
  36. package/npm/win32-arm64-msvc/package.json +23 -0
  37. package/npm/win32-x64-msvc/README.md +3 -0
  38. package/npm/win32-x64-msvc/package.json +23 -0
  39. package/package.json +51 -16
  40. package/src/artifact.rs +217 -0
  41. package/src/attestation_query.rs +104 -0
  42. package/src/audit.rs +128 -0
  43. package/src/commit_sign.rs +63 -0
  44. package/src/device.rs +212 -0
  45. package/src/diagnostics.rs +106 -0
  46. package/src/error.rs +5 -0
  47. package/src/helpers.rs +60 -0
  48. package/src/identity.rs +467 -0
  49. package/src/lib.rs +26 -0
  50. package/src/org.rs +430 -0
  51. package/src/pairing.rs +454 -0
  52. package/src/policy.rs +147 -0
  53. package/src/sign.rs +215 -0
  54. package/src/trust.rs +189 -0
  55. package/src/types.rs +205 -0
  56. package/src/verify.rs +447 -0
  57. package/src/witness.rs +138 -0
  58. package/tsconfig.json +19 -0
  59. package/typedoc.json +18 -0
  60. package/vitest.config.ts +12 -0
package/lib/native.ts ADDED
@@ -0,0 +1,255 @@
1
+ // Type declarations for native napi-rs bindings (auto-generated at build time)
2
+ // This file provides typed access to the Rust #[napi] functions
3
+
4
+ export interface NapiVerificationResult {
5
+ valid: boolean
6
+ error?: string | null
7
+ errorCode?: string | null
8
+ }
9
+
10
+ export interface NapiVerificationStatus {
11
+ statusType: string
12
+ at?: string | null
13
+ step?: number | null
14
+ missingLink?: string | null
15
+ required?: number | null
16
+ verified?: number | null
17
+ }
18
+
19
+ export interface NapiChainLink {
20
+ issuer: string
21
+ subject: string
22
+ valid: boolean
23
+ error?: string | null
24
+ }
25
+
26
+ export interface NapiVerificationReport {
27
+ status: NapiVerificationStatus
28
+ chain: NapiChainLink[]
29
+ warnings: string[]
30
+ }
31
+
32
+ export interface NapiIdentityResult {
33
+ did: string
34
+ keyAlias: string
35
+ publicKeyHex: string
36
+ }
37
+
38
+ export interface NapiAgentIdentityBundle {
39
+ agentDid: string
40
+ keyAlias: string
41
+ attestationJson: string
42
+ publicKeyHex: string
43
+ repoPath?: string | null
44
+ }
45
+
46
+ export interface NapiDelegatedAgentBundle {
47
+ agentDid: string
48
+ keyAlias: string
49
+ attestationJson: string
50
+ publicKeyHex: string
51
+ repoPath?: string | null
52
+ }
53
+
54
+ export interface NapiRotationResult {
55
+ controllerDid: string
56
+ newKeyFingerprint: string
57
+ previousKeyFingerprint: string
58
+ sequence: number
59
+ }
60
+
61
+ export interface NapiLinkResult {
62
+ deviceDid: string
63
+ attestationId: string
64
+ }
65
+
66
+ export interface NapiExtensionResult {
67
+ deviceDid: string
68
+ newExpiresAt: string
69
+ previousExpiresAt?: string | null
70
+ }
71
+
72
+ export interface NapiCommitSignResult {
73
+ signature: string
74
+ signerDid: string
75
+ }
76
+
77
+ export interface NapiActionEnvelope {
78
+ envelopeJson: string
79
+ signatureHex: string
80
+ signerDid: string
81
+ }
82
+
83
+ export interface NapiCommitSignPemResult {
84
+ signaturePem: string
85
+ method: string
86
+ namespace: string
87
+ }
88
+
89
+ export interface NapiOrgResult {
90
+ orgPrefix: string
91
+ orgDid: string
92
+ label: string
93
+ repoPath: string
94
+ }
95
+
96
+ export interface NapiOrgMember {
97
+ memberDid: string
98
+ role: string
99
+ capabilitiesJson: string
100
+ issuerDid: string
101
+ attestationRid: string
102
+ revoked: boolean
103
+ expiresAt?: string | null
104
+ }
105
+
106
+ export interface NapiAttestation {
107
+ rid: string
108
+ issuer: string
109
+ subject: string
110
+ deviceDid: string
111
+ capabilities: string[]
112
+ signerType?: string | null
113
+ expiresAt?: string | null
114
+ revokedAt?: string | null
115
+ createdAt?: string | null
116
+ delegatedBy?: string | null
117
+ json: string
118
+ }
119
+
120
+ export interface NapiPinnedIdentity {
121
+ did: string
122
+ label?: string | null
123
+ trustLevel: string
124
+ firstSeen: string
125
+ kelSequence?: number | null
126
+ pinnedAt: string
127
+ }
128
+
129
+ export interface NapiWitnessResult {
130
+ url: string
131
+ did?: string | null
132
+ label?: string | null
133
+ }
134
+
135
+ export interface NapiArtifactResult {
136
+ attestationJson: string
137
+ rid: string
138
+ digest: string
139
+ fileSize: number
140
+ }
141
+
142
+ export interface NapiPolicyDecision {
143
+ outcome: string
144
+ reason: string
145
+ message: string
146
+ }
147
+
148
+ export interface NapiPairingSession {
149
+ sessionId: string
150
+ shortCode: string
151
+ endpoint: string
152
+ token: string
153
+ controllerDid: string
154
+ }
155
+
156
+ export interface NapiPairingResponse {
157
+ deviceDid: string
158
+ deviceName?: string | null
159
+ devicePublicKeyHex: string
160
+ }
161
+
162
+ export interface NapiPairingResult {
163
+ deviceDid: string
164
+ deviceName?: string | null
165
+ attestationRid: string
166
+ }
167
+
168
+ export interface NapiPairingHandleInstance {
169
+ session: NapiPairingSession
170
+ waitForResponse(timeoutSecs?: number | null): Promise<NapiPairingResponse>
171
+ complete(deviceDid: string, devicePublicKeyHex: string, repoPath: string, capabilitiesJson?: string | null, passphrase?: string | null): Promise<NapiPairingResult>
172
+ stop(): Promise<void>
173
+ }
174
+
175
+ export interface NativeBindings {
176
+ version(): string
177
+
178
+ // Identity
179
+ createIdentity(keyAlias: string, repoPath: string, passphrase?: string | null): NapiIdentityResult
180
+ createAgentIdentity(agentName: string, capabilities: string[], repoPath: string, passphrase?: string | null): NapiAgentIdentityBundle
181
+ delegateAgent(agentName: string, capabilities: string[], parentRepoPath: string, passphrase?: string | null, expiresInDays?: number | null, identityDid?: string | null): NapiDelegatedAgentBundle
182
+ rotateIdentityKeys(repoPath: string, identityKeyAlias?: string | null, nextKeyAlias?: string | null, passphrase?: string | null): NapiRotationResult
183
+ getIdentityPublicKey(identityDid: string, repoPath: string, passphrase?: string | null): string
184
+
185
+ // Device
186
+ linkDeviceToIdentity(identityKeyAlias: string, capabilities: string[], repoPath: string, passphrase?: string | null, expiresInDays?: number | null): NapiLinkResult
187
+ revokeDeviceFromIdentity(deviceDid: string, identityKeyAlias: string, repoPath: string, passphrase?: string | null, note?: string | null): void
188
+ extendDeviceAuthorization(deviceDid: string, identityKeyAlias: string, days: number, repoPath: string, passphrase?: string | null): NapiExtensionResult
189
+
190
+ // Signing
191
+ signAsIdentity(message: Buffer, identityDid: string, repoPath: string, passphrase?: string | null): NapiCommitSignResult
192
+ signActionAsIdentity(actionType: string, payloadJson: string, identityDid: string, repoPath: string, passphrase?: string | null): NapiActionEnvelope
193
+ signAsAgent(message: Buffer, keyAlias: string, repoPath: string, passphrase?: string | null): NapiCommitSignResult
194
+ signActionAsAgent(actionType: string, payloadJson: string, keyAlias: string, agentDid: string, repoPath: string, passphrase?: string | null): NapiActionEnvelope
195
+
196
+ // Commit signing
197
+ signCommit(data: Buffer, identityKeyAlias: string, repoPath: string, passphrase?: string | null): NapiCommitSignPemResult
198
+
199
+ // Org
200
+ createOrg(label: string, repoPath: string, passphrase?: string | null): NapiOrgResult
201
+ addOrgMember(orgDid: string, memberDid: string, role: string, repoPath: string, capabilitiesJson?: string | null, passphrase?: string | null, note?: string | null, memberPublicKeyHex?: string | null): NapiOrgMember
202
+ revokeOrgMember(orgDid: string, memberDid: string, repoPath: string, passphrase?: string | null, note?: string | null, memberPublicKeyHex?: string | null): NapiOrgMember
203
+ listOrgMembers(orgDid: string, includeRevoked: boolean, repoPath: string): string
204
+
205
+ // Attestation query
206
+ listAttestations(repoPath: string): NapiAttestation[]
207
+ listAttestationsByDevice(repoPath: string, deviceDid: string): NapiAttestation[]
208
+ getLatestAttestation(repoPath: string, deviceDid: string): NapiAttestation | null
209
+
210
+ // Trust
211
+ pinIdentity(did: string, repoPath: string, label?: string | null, trustLevel?: string | null): NapiPinnedIdentity
212
+ removePinnedIdentity(did: string, repoPath: string): void
213
+ listPinnedIdentities(repoPath: string): string
214
+ getPinnedIdentity(did: string, repoPath: string): NapiPinnedIdentity | null
215
+
216
+ // Witness
217
+ addWitness(urlStr: string, repoPath: string, label?: string | null): NapiWitnessResult
218
+ removeWitness(urlStr: string, repoPath: string): void
219
+ listWitnesses(repoPath: string): string
220
+
221
+ // Artifact
222
+ signArtifact(filePath: string, identityKeyAlias: string, repoPath: string, passphrase?: string | null, expiresInDays?: number | null, note?: string | null): NapiArtifactResult
223
+ signArtifactBytes(data: Buffer, identityKeyAlias: string, repoPath: string, passphrase?: string | null, expiresInDays?: number | null, note?: string | null): NapiArtifactResult
224
+
225
+ // Audit
226
+ generateAuditReport(targetRepoPath: string, authsRepoPath: string, since?: string | null, until?: string | null, author?: string | null, limit?: number | null): string
227
+
228
+ // Diagnostics
229
+ runDiagnostics(repoPath: string, passphrase?: string | null): string
230
+
231
+ // Policy
232
+ compilePolicy(policyJson: string): string
233
+ evaluatePolicy(compiledPolicyJson: string, issuer: string, subject: string, capabilities?: string[] | null, role?: string | null, revoked?: boolean | null, expiresAt?: string | null, repo?: string | null, environment?: string | null, signerType?: string | null, delegatedBy?: string | null, chainDepth?: number | null): NapiPolicyDecision
234
+
235
+ // Pairing
236
+ NapiPairingHandle: {
237
+ createSession(repoPath: string, capabilitiesJson?: string | null, timeoutSecs?: number | null, bindAddress?: string | null, enableMdns?: boolean | null, passphrase?: string | null): Promise<NapiPairingHandleInstance>
238
+ }
239
+ joinPairingSession(shortCode: string, endpoint: string, token: string, repoPath: string, deviceName?: string | null, passphrase?: string | null): Promise<NapiPairingResponse>
240
+
241
+ // Verification
242
+ verifyAttestation(attestationJson: string, issuerPkHex: string): Promise<NapiVerificationResult>
243
+ verifyChain(attestationsJson: string[], rootPkHex: string): Promise<NapiVerificationReport>
244
+ verifyDeviceAuthorization(identityDid: string, deviceDid: string, attestationsJson: string[], identityPkHex: string): Promise<NapiVerificationReport>
245
+ verifyAttestationWithCapability(attestationJson: string, issuerPkHex: string, requiredCapability: string): Promise<NapiVerificationResult>
246
+ verifyChainWithCapability(attestationsJson: string[], rootPkHex: string, requiredCapability: string): Promise<NapiVerificationReport>
247
+ verifyAtTime(attestationJson: string, issuerPkHex: string, atRfc3339: string): Promise<NapiVerificationResult>
248
+ verifyAtTimeWithCapability(attestationJson: string, issuerPkHex: string, atRfc3339: string, requiredCapability: string): Promise<NapiVerificationResult>
249
+ verifyChainWithWitnesses(attestationsJson: string[], rootPkHex: string, receiptsJson: string[], witnessKeysJson: string[], threshold: number): Promise<NapiVerificationReport>
250
+ }
251
+
252
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
253
+ const native: NativeBindings = require('../index.js')
254
+
255
+ export default native
package/lib/org.ts ADDED
@@ -0,0 +1,235 @@
1
+ import native from './native'
2
+ import { mapNativeError, OrgError } from './errors'
3
+ import type { Auths } from './client'
4
+
5
+ /** Result of creating an organization. */
6
+ export interface OrgResult {
7
+ /** Internal prefix for the organization. */
8
+ orgPrefix: string
9
+ /** The organization's KERI DID. */
10
+ orgDid: string
11
+ /** Human-readable label. */
12
+ label: string
13
+ /** Path to the registry storing the organization. */
14
+ repoPath: string
15
+ }
16
+
17
+ /** An organization member record. */
18
+ export interface OrgMember {
19
+ /** DID of the member. */
20
+ memberDid: string
21
+ /** Role within the organization (e.g. `'admin'`, `'member'`). */
22
+ role: string
23
+ /** Capabilities granted to this member. */
24
+ capabilities: string[]
25
+ /** DID of the admin who added this member. */
26
+ issuerDid: string
27
+ /** Resource identifier of the membership attestation. */
28
+ attestationRid: string
29
+ /** Whether the membership has been revoked. */
30
+ revoked: boolean
31
+ /** Expiration timestamp (RFC 3339), or `null` if no expiry. */
32
+ expiresAt: string | null
33
+ }
34
+
35
+ /**
36
+ * Check whether an organization member has admin role.
37
+ *
38
+ * @param member - The organization member to check.
39
+ * @returns `true` if the member's role is `'admin'`.
40
+ */
41
+ export function isAdmin(member: OrgMember): boolean {
42
+ return member.role === 'admin'
43
+ }
44
+
45
+ /** Options for {@link OrgService.create}. */
46
+ export interface CreateOrgOptions {
47
+ /** Human-readable label for the organization. */
48
+ label: string
49
+ /** Override the client's repo path. */
50
+ repoPath?: string
51
+ /** Override the client's passphrase. */
52
+ passphrase?: string
53
+ }
54
+
55
+ /** Options for {@link OrgService.addMember}. */
56
+ export interface AddOrgMemberOptions {
57
+ /** DID of the organization. */
58
+ orgDid: string
59
+ /** DID of the member to add. */
60
+ memberDid: string
61
+ /** Role to assign (e.g. `'admin'`, `'member'`). */
62
+ role: string
63
+ /** Capabilities to grant the member. */
64
+ capabilities?: string[]
65
+ /** Override the client's passphrase. */
66
+ passphrase?: string
67
+ /** Optional note for the membership record. */
68
+ note?: string
69
+ /** Hex-encoded public key of the member (required for cross-repo adds). */
70
+ memberPublicKeyHex?: string
71
+ }
72
+
73
+ /** Options for {@link OrgService.revokeMember}. */
74
+ export interface RevokeOrgMemberOptions {
75
+ /** DID of the organization. */
76
+ orgDid: string
77
+ /** DID of the member to revoke. */
78
+ memberDid: string
79
+ /** Override the client's passphrase. */
80
+ passphrase?: string
81
+ /** Optional revocation note. */
82
+ note?: string
83
+ /** Hex-encoded public key of the member. */
84
+ memberPublicKeyHex?: string
85
+ }
86
+
87
+ /** Options for {@link OrgService.listMembers}. */
88
+ export interface ListOrgMembersOptions {
89
+ /** DID of the organization. */
90
+ orgDid: string
91
+ /** Whether to include revoked members. Defaults to `false`. */
92
+ includeRevoked?: boolean
93
+ }
94
+
95
+ /**
96
+ * Manages organizations and their membership.
97
+ *
98
+ * Access via {@link Auths.orgs}.
99
+ *
100
+ * @example
101
+ * ```typescript
102
+ * const org = auths.orgs.create({ label: 'my-team' })
103
+ * auths.orgs.addMember({
104
+ * orgDid: org.orgDid,
105
+ * memberDid: dev.did,
106
+ * role: 'member',
107
+ * memberPublicKeyHex: dev.publicKey,
108
+ * })
109
+ * ```
110
+ */
111
+ export class OrgService {
112
+ constructor(private client: Auths) {}
113
+
114
+ /**
115
+ * Creates a new organization.
116
+ *
117
+ * @param opts - Organization options.
118
+ * @returns The created organization.
119
+ * @throws {@link OrgError} if creation fails.
120
+ *
121
+ * @example
122
+ * ```typescript
123
+ * const org = auths.orgs.create({ label: 'engineering' })
124
+ * console.log(org.orgDid) // did:keri:...
125
+ * ```
126
+ */
127
+ create(opts: CreateOrgOptions): OrgResult {
128
+ const rp = opts.repoPath ?? this.client.repoPath
129
+ const pp = opts.passphrase ?? this.client.passphrase
130
+ try {
131
+ return native.createOrg(opts.label, rp, pp)
132
+ } catch (err) {
133
+ throw mapNativeError(err, OrgError)
134
+ }
135
+ }
136
+
137
+ /**
138
+ * Adds a member to an organization.
139
+ *
140
+ * @param opts - Member options.
141
+ * @returns The new member record.
142
+ * @throws {@link OrgError} if the operation fails.
143
+ *
144
+ * @example
145
+ * ```typescript
146
+ * const member = auths.orgs.addMember({
147
+ * orgDid: org.orgDid,
148
+ * memberDid: dev.did,
149
+ * role: 'member',
150
+ * memberPublicKeyHex: dev.publicKey,
151
+ * })
152
+ * ```
153
+ */
154
+ addMember(opts: AddOrgMemberOptions): OrgMember {
155
+ const pp = opts.passphrase ?? this.client.passphrase
156
+ const capsJson = opts.capabilities ? JSON.stringify(opts.capabilities) : null
157
+ try {
158
+ const result = native.addOrgMember(
159
+ opts.orgDid,
160
+ opts.memberDid,
161
+ opts.role,
162
+ this.client.repoPath,
163
+ capsJson,
164
+ pp,
165
+ opts.note ?? null,
166
+ opts.memberPublicKeyHex ?? null,
167
+ )
168
+ return {
169
+ memberDid: result.memberDid,
170
+ role: result.role,
171
+ capabilities: JSON.parse(result.capabilitiesJson || '[]'),
172
+ issuerDid: result.issuerDid,
173
+ attestationRid: result.attestationRid,
174
+ revoked: result.revoked,
175
+ expiresAt: result.expiresAt ?? null,
176
+ }
177
+ } catch (err) {
178
+ throw mapNativeError(err, OrgError)
179
+ }
180
+ }
181
+
182
+ /**
183
+ * Revokes a member's access to an organization.
184
+ *
185
+ * @param opts - Revocation options.
186
+ * @returns The updated member record with `revoked: true`.
187
+ * @throws {@link OrgError} if the operation fails.
188
+ */
189
+ revokeMember(opts: RevokeOrgMemberOptions): OrgMember {
190
+ const pp = opts.passphrase ?? this.client.passphrase
191
+ try {
192
+ const result = native.revokeOrgMember(
193
+ opts.orgDid,
194
+ opts.memberDid,
195
+ this.client.repoPath,
196
+ pp,
197
+ opts.note ?? null,
198
+ opts.memberPublicKeyHex ?? null,
199
+ )
200
+ return {
201
+ memberDid: result.memberDid,
202
+ role: result.role,
203
+ capabilities: JSON.parse(result.capabilitiesJson || '[]'),
204
+ issuerDid: result.issuerDid,
205
+ attestationRid: result.attestationRid,
206
+ revoked: result.revoked,
207
+ expiresAt: result.expiresAt ?? null,
208
+ }
209
+ } catch (err) {
210
+ throw mapNativeError(err, OrgError)
211
+ }
212
+ }
213
+
214
+ /**
215
+ * Lists members of an organization.
216
+ *
217
+ * @param opts - List options.
218
+ * @returns Array of member records.
219
+ * @throws {@link OrgError} if the operation fails.
220
+ *
221
+ * @example
222
+ * ```typescript
223
+ * const members = auths.orgs.listMembers({ orgDid: org.orgDid })
224
+ * console.log(members.length)
225
+ * ```
226
+ */
227
+ listMembers(opts: ListOrgMembersOptions): OrgMember[] {
228
+ try {
229
+ const json = native.listOrgMembers(opts.orgDid, opts.includeRevoked ?? false, this.client.repoPath)
230
+ return JSON.parse(json)
231
+ } catch (err) {
232
+ throw mapNativeError(err, OrgError)
233
+ }
234
+ }
235
+ }