@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.
- package/Cargo.toml +45 -0
- package/README.md +163 -4
- package/__test__/client.spec.ts +78 -0
- package/__test__/exports.spec.ts +57 -0
- package/__test__/integration.spec.ts +407 -0
- package/__test__/policy.spec.ts +202 -0
- package/__test__/verify.spec.ts +88 -0
- package/build.rs +5 -0
- package/index.d.ts +259 -0
- package/index.js +622 -1
- package/lib/artifacts.ts +124 -0
- package/lib/attestations.ts +126 -0
- package/lib/audit.ts +189 -0
- package/lib/client.ts +293 -0
- package/lib/commits.ts +70 -0
- package/lib/devices.ts +178 -0
- package/lib/errors.ts +306 -0
- package/lib/identity.ts +280 -0
- package/lib/index.ts +125 -0
- package/lib/native.ts +255 -0
- package/lib/org.ts +235 -0
- package/lib/pairing.ts +271 -0
- package/lib/policy.ts +669 -0
- package/lib/signing.ts +204 -0
- package/lib/trust.ts +152 -0
- package/lib/types.ts +179 -0
- package/lib/verify.ts +241 -0
- package/lib/witness.ts +91 -0
- package/npm/darwin-arm64/README.md +3 -0
- package/npm/darwin-arm64/package.json +23 -0
- package/npm/linux-arm64-gnu/README.md +3 -0
- package/npm/linux-arm64-gnu/package.json +26 -0
- package/npm/linux-x64-gnu/README.md +3 -0
- package/npm/linux-x64-gnu/package.json +26 -0
- package/npm/win32-arm64-msvc/README.md +3 -0
- package/npm/win32-arm64-msvc/package.json +23 -0
- package/npm/win32-x64-msvc/README.md +3 -0
- package/npm/win32-x64-msvc/package.json +23 -0
- package/package.json +51 -16
- package/src/artifact.rs +217 -0
- package/src/attestation_query.rs +104 -0
- package/src/audit.rs +128 -0
- package/src/commit_sign.rs +63 -0
- package/src/device.rs +212 -0
- package/src/diagnostics.rs +106 -0
- package/src/error.rs +5 -0
- package/src/helpers.rs +60 -0
- package/src/identity.rs +467 -0
- package/src/lib.rs +26 -0
- package/src/org.rs +430 -0
- package/src/pairing.rs +454 -0
- package/src/policy.rs +147 -0
- package/src/sign.rs +215 -0
- package/src/trust.rs +189 -0
- package/src/types.rs +205 -0
- package/src/verify.rs +447 -0
- package/src/witness.rs +138 -0
- package/tsconfig.json +19 -0
- package/typedoc.json +18 -0
- package/vitest.config.ts +12 -0
package/Cargo.toml
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "auths-node"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
edition = "2024"
|
|
5
|
+
description = "Node.js bindings for the Auths decentralized identity SDK"
|
|
6
|
+
license = "Apache-2.0"
|
|
7
|
+
publish = false
|
|
8
|
+
|
|
9
|
+
[workspace]
|
|
10
|
+
|
|
11
|
+
[lib]
|
|
12
|
+
crate-type = ["cdylib"]
|
|
13
|
+
|
|
14
|
+
[dependencies]
|
|
15
|
+
napi = { version = "3", default-features = false, features = ["napi4", "async", "tokio_rt", "serde-json"] }
|
|
16
|
+
napi-derive = "3"
|
|
17
|
+
|
|
18
|
+
# Core auths crates (same as auths-python)
|
|
19
|
+
auths-sdk = { path = "../../crates/auths-sdk" }
|
|
20
|
+
auths-core = { path = "../../crates/auths-core", features = ["keychain-file-fallback"] }
|
|
21
|
+
auths-id = { path = "../../crates/auths-id" }
|
|
22
|
+
auths-crypto = { path = "../../crates/auths-crypto" }
|
|
23
|
+
auths-verifier = { path = "../../crates/auths-verifier" }
|
|
24
|
+
auths-storage = { path = "../../crates/auths-storage", features = ["backend-git"] }
|
|
25
|
+
auths-policy = { path = "../../crates/auths-policy" }
|
|
26
|
+
auths-pairing-daemon = { path = "../../crates/auths-pairing-daemon" }
|
|
27
|
+
auths-infra-git = { path = "../../crates/auths-infra-git" }
|
|
28
|
+
|
|
29
|
+
# Utilities
|
|
30
|
+
serde = { version = "1", features = ["derive"] }
|
|
31
|
+
serde_json = "1"
|
|
32
|
+
tokio = { version = "1", features = ["sync", "net"] }
|
|
33
|
+
reqwest = { version = "0.13.2", default-features = false, features = ["rustls", "json"] }
|
|
34
|
+
hex = "0.4"
|
|
35
|
+
chrono = "0.4"
|
|
36
|
+
ring = "0.17"
|
|
37
|
+
json-canon = "=0.1.3"
|
|
38
|
+
sha2 = "0.10"
|
|
39
|
+
uuid = { version = "1", features = ["v4"] }
|
|
40
|
+
shellexpand = "3"
|
|
41
|
+
url = "2"
|
|
42
|
+
axum = "0.8"
|
|
43
|
+
|
|
44
|
+
[build-dependencies]
|
|
45
|
+
napi-build = "2"
|
package/README.md
CHANGED
|
@@ -1,7 +1,166 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Auths Node SDK
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Decentralized identity for developers and AI agents. Sign, verify, and manage cryptographic identities with Git-native storage.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Install
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
```bash
|
|
8
|
+
npm install @auths-dev/sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick start
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { Auths, verifyAttestation } from '@auths-dev/sdk'
|
|
15
|
+
|
|
16
|
+
const auths = new Auths()
|
|
17
|
+
|
|
18
|
+
// Verify an attestation
|
|
19
|
+
const result = verifyAttestation(attestationJson, publicKeyHex)
|
|
20
|
+
console.log(result.valid) // true
|
|
21
|
+
|
|
22
|
+
// Create an identity and sign
|
|
23
|
+
const identity = auths.identities.create({ label: 'laptop' })
|
|
24
|
+
const sig = auths.signAs({ message: Buffer.from('hello world'), identityDid: identity.did })
|
|
25
|
+
console.log(sig.signature) // hex-encoded Ed25519 signature
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Identity management
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { Auths } from '@auths-dev/sdk'
|
|
32
|
+
|
|
33
|
+
const auths = new Auths({ repoPath: '~/.auths' })
|
|
34
|
+
|
|
35
|
+
// Create a cryptographic identity
|
|
36
|
+
const identity = auths.identities.create({ label: 'laptop' })
|
|
37
|
+
console.log(identity.did) // did:keri:EBfd...
|
|
38
|
+
|
|
39
|
+
// Provision an agent (for CI, MCP servers, etc.)
|
|
40
|
+
const agent = auths.identities.delegateAgent({
|
|
41
|
+
identityDid: identity.did,
|
|
42
|
+
name: 'deploy-bot',
|
|
43
|
+
capabilities: ['sign'],
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
// Sign using the keychain-stored identity key
|
|
47
|
+
const result = auths.signAs({
|
|
48
|
+
message: Buffer.from('hello world'),
|
|
49
|
+
identityDid: identity.did,
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
// Link and manage devices
|
|
53
|
+
const device = auths.devices.link({
|
|
54
|
+
identityDid: identity.did,
|
|
55
|
+
capabilities: ['sign'],
|
|
56
|
+
})
|
|
57
|
+
auths.devices.revoke({
|
|
58
|
+
deviceDid: device.did,
|
|
59
|
+
identityDid: identity.did,
|
|
60
|
+
note: 'replaced',
|
|
61
|
+
})
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Policy engine
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
import { PolicyBuilder, evaluatePolicy } from '@auths-dev/sdk'
|
|
68
|
+
|
|
69
|
+
// Build a standard policy
|
|
70
|
+
const policy = PolicyBuilder.standard('sign_commit')
|
|
71
|
+
|
|
72
|
+
// Evaluate against a context
|
|
73
|
+
const decision = policy.evaluate({
|
|
74
|
+
issuer: 'did:keri:EOrg',
|
|
75
|
+
subject: 'did:key:zDevice',
|
|
76
|
+
capabilities: ['sign_commit'],
|
|
77
|
+
})
|
|
78
|
+
console.log(decision.allowed) // true
|
|
79
|
+
|
|
80
|
+
// Compose complex policies
|
|
81
|
+
const ciPolicy = new PolicyBuilder()
|
|
82
|
+
.notRevoked()
|
|
83
|
+
.notExpired()
|
|
84
|
+
.requireCapability('sign')
|
|
85
|
+
.requireAgent()
|
|
86
|
+
.requireRepo('org/repo')
|
|
87
|
+
.toJson()
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Organization management
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
const org = auths.orgs.create({ label: 'my-team' })
|
|
94
|
+
|
|
95
|
+
const member = auths.orgs.addMember({
|
|
96
|
+
orgDid: org.orgDid,
|
|
97
|
+
memberDid: devIdentity.did,
|
|
98
|
+
role: 'member',
|
|
99
|
+
memberPublicKeyHex: devIdentity.publicKey,
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
const members = auths.orgs.listMembers({ orgDid: org.orgDid })
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Verification
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
import {
|
|
109
|
+
verifyAttestation,
|
|
110
|
+
verifyChain,
|
|
111
|
+
verifyAttestationWithCapability,
|
|
112
|
+
} from '@auths-dev/sdk'
|
|
113
|
+
|
|
114
|
+
// Single attestation
|
|
115
|
+
const result = verifyAttestation(attestationJson, issuerPublicKeyHex)
|
|
116
|
+
|
|
117
|
+
// Attestation chain
|
|
118
|
+
const report = verifyChain(attestationChain, rootPublicKeyHex)
|
|
119
|
+
console.log(report.status.statusType) // 'Valid' | 'Invalid' | ...
|
|
120
|
+
|
|
121
|
+
// Capability-scoped verification
|
|
122
|
+
const capResult = verifyAttestationWithCapability(
|
|
123
|
+
attestationJson, issuerPublicKeyHex, 'sign_commit'
|
|
124
|
+
)
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Error handling
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
import { Auths, VerificationError, CryptoError, NetworkError } from '@auths-dev/sdk'
|
|
131
|
+
|
|
132
|
+
const auths = new Auths()
|
|
133
|
+
try {
|
|
134
|
+
const result = auths.signAs({ message: data, identityDid: did })
|
|
135
|
+
} catch (e) {
|
|
136
|
+
if (e instanceof CryptoError) {
|
|
137
|
+
console.log(e.code) // 'key_not_found'
|
|
138
|
+
console.log(e.message) // 'No key found for identity...'
|
|
139
|
+
}
|
|
140
|
+
if (e instanceof NetworkError && e.shouldRetry) {
|
|
141
|
+
// safe to retry
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
All errors inherit from `AuthsError` and carry `.code` and `.message`.
|
|
147
|
+
|
|
148
|
+
## Configuration
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
// Auto-discover (uses ~/.auths)
|
|
152
|
+
const auths = new Auths()
|
|
153
|
+
|
|
154
|
+
// Explicit repo path
|
|
155
|
+
const auths = new Auths({ repoPath: '/path/to/identity-repo' })
|
|
156
|
+
|
|
157
|
+
// With passphrase (or set AUTHS_PASSPHRASE env var)
|
|
158
|
+
const auths = new Auths({ passphrase: 'my-secret' })
|
|
159
|
+
|
|
160
|
+
// Headless / CI mode
|
|
161
|
+
// Set AUTHS_KEYCHAIN_BACKEND=file for environments without a system keychain
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## License
|
|
165
|
+
|
|
166
|
+
Apache-2.0
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
|
+
import { Auths } from '../lib/client'
|
|
3
|
+
import {
|
|
4
|
+
AuthsError,
|
|
5
|
+
VerificationError,
|
|
6
|
+
CryptoError,
|
|
7
|
+
KeychainError,
|
|
8
|
+
StorageError,
|
|
9
|
+
NetworkError,
|
|
10
|
+
IdentityError,
|
|
11
|
+
OrgError,
|
|
12
|
+
PairingError,
|
|
13
|
+
} from '../lib/errors'
|
|
14
|
+
|
|
15
|
+
describe('Auths client', () => {
|
|
16
|
+
it('instantiates with defaults', () => {
|
|
17
|
+
const auths = new Auths()
|
|
18
|
+
expect(auths.repoPath).toBe('~/.auths')
|
|
19
|
+
expect(auths.passphrase).toBeUndefined()
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
it('instantiates with custom config', () => {
|
|
23
|
+
const auths = new Auths({ repoPath: '/tmp/test-repo', passphrase: 'secret' })
|
|
24
|
+
expect(auths.repoPath).toBe('/tmp/test-repo')
|
|
25
|
+
expect(auths.passphrase).toBe('secret')
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
it('exposes all service properties', () => {
|
|
29
|
+
const auths = new Auths()
|
|
30
|
+
expect(auths.identities).toBeDefined()
|
|
31
|
+
expect(auths.devices).toBeDefined()
|
|
32
|
+
expect(auths.signing).toBeDefined()
|
|
33
|
+
expect(auths.orgs).toBeDefined()
|
|
34
|
+
expect(auths.trust).toBeDefined()
|
|
35
|
+
expect(auths.witnesses).toBeDefined()
|
|
36
|
+
expect(auths.attestations).toBeDefined()
|
|
37
|
+
expect(auths.artifacts).toBeDefined()
|
|
38
|
+
expect(auths.commits).toBeDefined()
|
|
39
|
+
expect(auths.audit).toBeDefined()
|
|
40
|
+
expect(auths.pairing).toBeDefined()
|
|
41
|
+
})
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
describe('error hierarchy', () => {
|
|
45
|
+
it('all error subclasses extend AuthsError', () => {
|
|
46
|
+
for (const Cls of [
|
|
47
|
+
VerificationError,
|
|
48
|
+
CryptoError,
|
|
49
|
+
KeychainError,
|
|
50
|
+
StorageError,
|
|
51
|
+
NetworkError,
|
|
52
|
+
IdentityError,
|
|
53
|
+
OrgError,
|
|
54
|
+
PairingError,
|
|
55
|
+
]) {
|
|
56
|
+
const err = new Cls('test')
|
|
57
|
+
expect(err).toBeInstanceOf(AuthsError)
|
|
58
|
+
expect(err).toBeInstanceOf(Error)
|
|
59
|
+
}
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
it('AuthsError has code and message', () => {
|
|
63
|
+
const err = new AuthsError('something broke')
|
|
64
|
+
err.code = 'AUTHS_TEST'
|
|
65
|
+
expect(err.message).toBe('something broke')
|
|
66
|
+
expect(err.code).toBe('AUTHS_TEST')
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
it('NetworkError has shouldRetry', () => {
|
|
70
|
+
const err = new NetworkError('timeout')
|
|
71
|
+
expect(err.shouldRetry).toBe(true)
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
it('PairingError has shouldRetry', () => {
|
|
75
|
+
const err = new PairingError('session expired')
|
|
76
|
+
expect(err.shouldRetry).toBe(true)
|
|
77
|
+
})
|
|
78
|
+
})
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
|
+
import * as auths from '../lib/index'
|
|
3
|
+
|
|
4
|
+
describe('top-level exports', () => {
|
|
5
|
+
it('exports Auths client', () => {
|
|
6
|
+
expect(auths.Auths).toBeDefined()
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
it('exports service classes', () => {
|
|
10
|
+
expect(auths.IdentityService).toBeDefined()
|
|
11
|
+
expect(auths.DeviceService).toBeDefined()
|
|
12
|
+
expect(auths.SigningService).toBeDefined()
|
|
13
|
+
expect(auths.OrgService).toBeDefined()
|
|
14
|
+
expect(auths.TrustService).toBeDefined()
|
|
15
|
+
expect(auths.WitnessService).toBeDefined()
|
|
16
|
+
expect(auths.AttestationService).toBeDefined()
|
|
17
|
+
expect(auths.ArtifactService).toBeDefined()
|
|
18
|
+
expect(auths.CommitService).toBeDefined()
|
|
19
|
+
expect(auths.AuditService).toBeDefined()
|
|
20
|
+
expect(auths.PairingService).toBeDefined()
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
it('exports PolicyBuilder and policy functions', () => {
|
|
24
|
+
expect(auths.PolicyBuilder).toBeDefined()
|
|
25
|
+
expect(auths.compilePolicy).toBeDefined()
|
|
26
|
+
expect(auths.evaluatePolicy).toBeDefined()
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
it('exports verification functions', () => {
|
|
30
|
+
expect(auths.verifyAttestation).toBeDefined()
|
|
31
|
+
expect(auths.verifyChain).toBeDefined()
|
|
32
|
+
expect(auths.verifyDeviceAuthorization).toBeDefined()
|
|
33
|
+
expect(auths.verifyAttestationWithCapability).toBeDefined()
|
|
34
|
+
expect(auths.verifyChainWithCapability).toBeDefined()
|
|
35
|
+
expect(auths.verifyAtTime).toBeDefined()
|
|
36
|
+
expect(auths.verifyAtTimeWithCapability).toBeDefined()
|
|
37
|
+
expect(auths.verifyChainWithWitnesses).toBeDefined()
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
it('exports error classes', () => {
|
|
41
|
+
expect(auths.AuthsError).toBeDefined()
|
|
42
|
+
expect(auths.VerificationError).toBeDefined()
|
|
43
|
+
expect(auths.CryptoError).toBeDefined()
|
|
44
|
+
expect(auths.KeychainError).toBeDefined()
|
|
45
|
+
expect(auths.StorageError).toBeDefined()
|
|
46
|
+
expect(auths.NetworkError).toBeDefined()
|
|
47
|
+
expect(auths.IdentityError).toBeDefined()
|
|
48
|
+
expect(auths.OrgError).toBeDefined()
|
|
49
|
+
expect(auths.PairingError).toBeDefined()
|
|
50
|
+
expect(auths.mapNativeError).toBeDefined()
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
it('exports version function', () => {
|
|
54
|
+
expect(auths.version).toBeDefined()
|
|
55
|
+
expect(typeof auths.version).toBe('function')
|
|
56
|
+
})
|
|
57
|
+
})
|