Skip to content

feat: adds auths-node SDK to mirror auths-python#60

Merged
bordumb merged 24 commits intomainfrom
fn-55
Mar 9, 2026
Merged

feat: adds auths-node SDK to mirror auths-python#60
bordumb merged 24 commits intomainfrom
fn-55

Conversation

@bordumb
Copy link
Contributor

@bordumb bordumb commented Mar 9, 2026

No description provided.

bordumb added 22 commits March 9, 2026 15:13
Sets up packages/auths-node/ with napi-rs v3 bindings, standalone
Cargo workspace (matching Python SDK pattern), all core crate
dependencies, vitest config, and TypeScript project config.
Implements the foundation layer for all binding modules:
- error.rs: map_error() and format_error() for [AUTHS_CODE] format
- helpers.rs: resolve_passphrase, resolve_repo_path, make_env_config,
  get_keychain, resolve_key_alias (factored from Python SDK inline pattern)
- types.rs: NapiVerificationResult, NapiVerificationStatus, NapiChainLink,
  NapiVerificationReport with From impls for core types
…dings

Add Rust napi-rs bindings for all core SDK operations:
- identity.rs: create_identity, create_agent_identity, delegate_agent, rotate_identity_keys, get_identity_public_key
- device.rs: link_device_to_identity, revoke_device_from_identity, extend_device_authorization
- sign.rs: sign_as_identity, sign_action_as_identity, sign_as_agent, sign_action_as_agent
- verify.rs: verify_attestation, verify_chain, verify_device_authorization, verify_at_time, verify_chain_with_witnesses, plus capability variants
- types.rs: all napi-compatible wrapper types with From impls

Also fix clippy needless_borrows_for_generic_args in auths-cli verify.rs
Add Stripe-style TypeScript SDK:
- lib/errors.ts: AuthsError hierarchy (8 typed subclasses) + mapNativeError parser
- lib/client.ts: Auths class with service properties and convenience methods
- lib/identity.ts: IdentityService (create, createAgent, delegateAgent, rotate, getPublicKey)
- lib/devices.ts: DeviceService (link, revoke, extend)
- lib/signing.ts: SigningService (signAsIdentity, signActionAsIdentity, signAsAgent, signActionAsAgent)
- lib/verify.ts: standalone verification functions (attestation, chain, device, time-pinned, witnesses)
- lib/native.ts: typed wrapper for napi-rs native bindings
- lib/index.ts: unified exports
…cs, commit bindings

Complete Rust napi-rs binding coverage:
- org.rs: create_org, add_org_member, revoke_org_member, list_org_members
- attestation_query.rs: list_attestations, list_attestations_by_device, get_latest_attestation
- trust.rs: pin_identity, remove_pinned_identity, list_pinned_identities, get_pinned_identity
- witness.rs: add_witness, remove_witness, list_witnesses
- artifact.rs: sign_artifact, sign_artifact_bytes
- audit.rs: generate_audit_report
- diagnostics.rs: run_diagnostics
- commit_sign.rs: sign_commit
Remove blanket #![allow(clippy::unwrap_used, clippy::expect_used)] from
CLI lib.rs and main.rs. Fix individual unwrap() sites:

- Replace serde_json::to_string().unwrap() with ? in verify_commit,
  artifact/verify, device/verify_attestation
- Replace Path::to_str().unwrap() with .ok_or_else() or .arg() for
  Command args in bin/sign, init_helpers
- Replace list.last().unwrap() with let-else in org.rs
- Add #[allow] with INVARIANT comments for provably safe expects:
  key.rs, utils.rs, device/authorization.rs, scim.rs, pair/common.rs,
  pair/online.rs

Add unwrap() policy section to CLAUDE.md documenting the project's
approach to unwrap/expect in production code.
- client.spec.ts: client instantiation, service properties, error hierarchy
- policy.spec.ts: PolicyBuilder fluent API, compilePolicy, evaluatePolicy
- verify.spec.ts: all verification functions with edge cases
- integration.spec.ts: full round-trip identity/device/signing/trust/witness/audit/org/pairing
- exports.spec.ts: verify all top-level exports are defined
- node-sdk.yml: build + test on Ubuntu and macOS, Rust lint check
- publish-node.yml: cross-compile for 8 targets, test wheels, publish to npm
- Fix Vec<u8> -> napi::Buffer for signing functions (napi maps Vec<u8> to Array<number>)
- Fix make_signer to use actual repo_path instead of hardcoded ~/.auths
- Fix get_identity_public_key to accept repo_path parameter
- Fix extend_device_authorization to use resolve_key_alias for DID inputs
- Fix NetworkError/PairingError shouldRetry default to true
- Fix integration tests to use correct TS field names (publicKey, did, name, etc.)
- Fix witness URL expectation (no trailing slash, matches Python SDK)
- Fix version test to require native index.js directly
…eychain config, diagnostics passphrase

- Issue 7: Remove unused map_error from error.rs
- Issue 10: Add exports field to package.json for Node 20+ resolution
- Issue 8: Add afterAll cleanup for temp directories in integration tests
- Issue 5: Use KeychainConfig::from_env() instead of hardcoding file backend
- Issue 6: Add passphrase parameter to run_diagnostics
… napi tokio_rt

- Remove manual RUNTIME OnceLock from verify.rs
- Convert all verify functions to async fn with #[napi] (uses napi's built-in tokio_rt)
- Replace runtime().block_on(...) with .await
- Update TypeScript types to return Promise
- Trim tokio features from full to sync+net
…mbol.dispose

- Issue 2+3: Replace ACTIVE_SESSION global singleton with NapiPairingHandle class
- Handle owned per-session, supports multiple concurrent sessions
- All pairing methods now async (uses napi tokio_rt)
- complete() and stop() are methods on the handle instance
- Drop impl aborts server task on GC
- Issue 9: Add Symbol.dispose and Symbol.asyncDispose to PairingService
- Update verify tests for async API
- Issue 4: Replace manual unsigned JSON construction in create_agent_identity
- Use link_device() for proper signed self-attestation
- Follow same pattern as delegate_agent for consistency
- Defer Arc wrapping until after initialize_registry_identity call
- Test concurrent pairing sessions (validates singleton removal)
- Test waitForResponse/complete without session throws properly
- Test verify functions return Promises (validates async migration)
- Test agent attestation has proper signed fields (validates link_device usage)
list_aliases_for_identity() could return the next-rotation key instead
of the primary key. Switch to list_aliases_for_identity_with_role() with
KeyRole::Primary in both Node and Python SDKs.
@bordumb bordumb self-assigned this Mar 9, 2026
@vercel
Copy link

vercel bot commented Mar 9, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
auths Ready Ready Preview, Comment Mar 9, 2026 6:13pm

bordumb added 2 commits March 9, 2026 18:08
- Node agent signing now passes repo_path instead of hardcoding ~/.auths
- Both SDKs use list_aliases_for_identity_with_role(KeyRole::Primary)
  in pairing instead of fragile --next-- string filtering
cargo fmt --all only formats workspace members. auths-node and
auths-python are standalone packages, so add explicit manifest-path
invocations for both. Apply formatting to all previously unformatted
files.
@bordumb bordumb merged commit 5a4a2b2 into main Mar 9, 2026
9 of 11 checks passed
@bordumb bordumb deleted the fn-55 branch March 9, 2026 18:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant