
Research
Supply Chain Attack on Axios Pulls Malicious Dependency from npm
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.
@atcute/identity
Advanced tools
syntax, type definitions and schemas for atproto handles, DIDs and DID documents
types, schemas, and utilities for working with AT Protocol identities.
npm install @atcute/identity
in AT Protocol, users are identified by DIDs (decentralized identifiers). this package provides tools for working with DIDs and DID documents - the documents that describe a user's identity, including their handle, PDS location, and cryptographic keys.
for resolving handles and DIDs (fetching their documents), see @atcute/identity-resolver.
AT Protocol supports two DID methods: did:plc and did:web. use the type guards to check which
method a DID uses:
import { isPlcDid, isWebDid, isAtprotoDid } from '@atcute/identity';
const did = 'did:plc:z72i7hdynmk6r22z27h6tvur';
if (isPlcDid(did)) {
// did:plc identifier
console.log('PLC DID');
}
if (isWebDid(did)) {
// did:web identifier (general, includes custom paths)
console.log('Web DID');
}
if (isAtprotoDid(did)) {
// either did:plc or atproto-compatible did:web
console.log('AT Protocol DID');
}
isAtprotoDid checks for DIDs that are valid in AT Protocol - this excludes did:web identifiers
with custom paths, which atproto doesn't support.
import { extractDidMethod } from '@atcute/identity';
const method = extractDidMethod('did:plc:z72i7hdynmk6r22z27h6tvur');
// -> "plc"
convert a did:web identifier to its DID document URL:
import { webDidToDocumentUrl, normalizeWebDid } from '@atcute/identity';
// simple domain
const url = webDidToDocumentUrl('did:web:example.com');
// -> URL { href: "https://example.com/.well-known/did.json" }
// with path
const url2 = webDidToDocumentUrl('did:web:example.com:users:alice');
// -> URL { href: "https://example.com/users/alice/did.json" }
// normalize for comparison
const normalized = normalizeWebDid('did:web:EXAMPLE.COM');
// -> "did:web:example.com"
once you have a DID document (from a resolver or API), extract information using the utility functions:
import {
getPdsEndpoint,
getAtprotoHandle,
getAtprotoVerificationMaterial,
getLabelerEndpoint,
} from '@atcute/identity';
import type { DidDocument } from '@atcute/identity';
const doc: DidDocument = {
'@context': ['https://www.w3.org/ns/did/v1'],
id: 'did:plc:z72i7hdynmk6r22z27h6tvur',
alsoKnownAs: ['at://bsky.app'],
verificationMethod: [
{
id: 'did:plc:z72i7hdynmk6r22z27h6tvur#atproto',
type: 'Multikey',
controller: 'did:plc:z72i7hdynmk6r22z27h6tvur',
publicKeyMultibase: 'zDnaek...',
},
],
service: [
{
id: '#atproto_pds',
type: 'AtprotoPersonalDataServer',
serviceEndpoint: 'https://morel.us-east.host.bsky.network',
},
],
};
// get the user's PDS URL
const pds = getPdsEndpoint(doc);
// -> "https://morel.us-east.host.bsky.network"
// get the user's handle
const handle = getAtprotoHandle(doc);
// -> "bsky.app"
// get the signing key material
const key = getAtprotoVerificationMaterial(doc);
// -> { type: "Multikey", publicKeyMultibase: "zDnaek..." }
extract specific service endpoints from DID documents:
import {
getPdsEndpoint,
getLabelerEndpoint,
getBlueskyChatEndpoint,
getBlueskyFeedgenEndpoint,
getBlueskyNotificationEndpoint,
getAtprotoServiceEndpoint,
} from '@atcute/identity';
// standard helpers for common services
const pds = getPdsEndpoint(doc); // #atproto_pds
const labeler = getLabelerEndpoint(doc); // #atproto_labeler
const chat = getBlueskyChatEndpoint(doc); // #bsky_chat
const feedgen = getBlueskyFeedgenEndpoint(doc); // #bsky_fg
const notif = getBlueskyNotificationEndpoint(doc); // #bsky_notif
// or use the generic helper for custom services
const custom = getAtprotoServiceEndpoint(doc, {
id: '#my_service',
type: 'MyServiceType', // optional type filter
});
use the validation schemas to check if a DID document is well-formed:
import { defs } from '@atcute/identity';
const result = defs.didDocument.try(unknownData);
if (result.ok) {
// result.value is a validated DidDocument
console.log(result.value.id);
} else {
// validation failed
console.error('invalid DID document');
}
the schema validates:
@context, id)the package exports TypeScript types for DID document structures:
import type { DidDocument, VerificationMethod, Service } from '@atcute/identity';
// DidDocument - the full DID document
// VerificationMethod - a verification method entry
// Service - a service endpoint entry
FAQs
syntax, type definitions and schemas for atproto handles, DIDs and DID documents
The npm package @atcute/identity receives a total of 1,028 weekly downloads. As such, @atcute/identity popularity was classified as popular.
We found that @atcute/identity demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.

Security News
TeamPCP is partnering with ransomware group Vect to turn open source supply chain attacks on tools like Trivy and LiteLLM into large-scale ransomware operations.