e4480bff5d8e155f235c002001c6e2621e557840
@push.rocks/smartregistry
A TypeScript library implementing the OCI Distribution Specification v1.1 for building container and artifact registries.
Features
- OCI Distribution Spec v1.1 Compliant: Implements all required and optional endpoints
- Cloud-Agnostic Storage: Uses @push.rocks/smartbucket for S3-compatible object storage
- Pluggable Authentication: Async callbacks for login and authorization
- Bearer Token Auth: JWT-based authentication following Docker Registry Token Authentication spec
- Programmatic API: Use as a library in any Node.js/TypeScript application
- Full CRUD Operations: Push, pull, list, and delete manifests and blobs
- Content Discovery: Tag listing and referrers API for artifact relationships
- Chunked Uploads: Support for large blob uploads with resumable sessions
Installation
npm install @push.rocks/smartregistry
# or
pnpm add @push.rocks/smartregistry
Usage
Basic Setup
import { SmartRegistry, IRegistryConfig, TLoginCallback, TAuthCallback } from '@push.rocks/smartregistry';
// Implement login callback
const loginCallback: TLoginCallback = async (credentials) => {
// Validate credentials and return JWT token
// This should create a proper JWT with required claims
return generateJWT(credentials.username);
};
// Implement authorization callback
const authCallback: TAuthCallback = async (token, repository, action) => {
// Validate token and check permissions
const claims = verifyJWT(token);
return hasPermission(claims, repository, action);
};
// Configure registry
const config: IRegistryConfig = {
storage: {
accessKey: 'your-s3-access-key',
accessSecret: 'your-s3-secret',
endpoint: 's3.amazonaws.com',
port: 443,
useSsl: true,
region: 'us-east-1',
bucketName: 'my-registry',
},
serviceName: 'my-registry',
tokenRealm: 'https://auth.example.com/token',
loginCallback,
authCallback,
};
// Create and initialize registry
const registry = new SmartRegistry(config);
await registry.init();
Integration with HTTP Server
import express from 'express';
const app = express();
// OCI Distribution API endpoints
app.get('/v2/', (req, res) => {
res.status(200).json({});
});
app.get('/v2/:name(*)/manifests/:reference', async (req, res) => {
const { name, reference } = req.params;
const token = req.headers.authorization?.replace('Bearer ', '');
const result = await registry.getManifest(name, reference, token);
if ('errors' in result) {
return res.status(404).json(result);
}
res.setHeader('Content-Type', result.contentType);
res.setHeader('Docker-Content-Digest', result.digest);
res.send(result.data);
});
app.get('/v2/:name(*)/blobs/:digest', async (req, res) => {
const { name, digest } = req.params;
const token = req.headers.authorization?.replace('Bearer ', '');
const result = await registry.getBlob(name, digest, token);
if ('errors' in result) {
return res.status(404).json(result);
}
res.setHeader('Content-Type', 'application/octet-stream');
res.send(result.data);
});
// ... implement other endpoints
app.listen(5000);
Authentication Flow
// Client requests without token
const challenge = registry.getAuthChallenge('library/nginx', ['pull', 'push']);
// Returns: Bearer realm="https://auth.example.com/token",service="my-registry",scope="repository:library/nginx:pull,push"
// Client authenticates
const token = await registry.login({ username: 'user', password: 'pass' });
// Client uses token for subsequent requests
const manifest = await registry.getManifest('library/nginx', 'latest', token);
API Reference
Pull Operations (Required)
getManifest(repository, reference, token?)- Download a manifestheadManifest(repository, reference, token?)- Check manifest existencegetBlob(repository, digest, token?, range?)- Download a blobheadBlob(repository, digest, token?)- Check blob existence
Push Operations
initiateUpload(repository, token, mountDigest?, fromRepository?)- Start blob uploaduploadChunk(uploadId, data, contentRange, token)- Upload blob chunkcompleteUpload(uploadId, digest, token, finalData?)- Finalize blob uploadputManifest(repository, reference, manifest, contentType, token)- Upload manifest
Content Discovery
listTags(repository, token?, pagination?)- List all tagsgetReferrers(repository, digest, token?, artifactType?)- Get referencing artifacts
Content Management
deleteManifest(repository, digest, token)- Delete manifestdeleteBlob(repository, digest, token)- Delete blobdeleteTag(repository, tag, token)- Delete tag
Authentication
login(credentials)- Get authentication tokengetAuthChallenge(repository, actions)- Generate WWW-Authenticate header
OCI Specification Compliance
This library implements:
- Pull Category (required): All manifest and blob retrieval operations
- Push Category: Complete blob upload workflow with chunked and monolithic modes
- Content Discovery: Tag listing and referrers API
- Content Management: Deletion operations for manifests, blobs, and tags
License
MIT
Contributing
See the main repository for contribution guidelines.
Description
Languages
TypeScript
100%