2025-11-27 23:53:05 +00:00
# @stack.gallery/registry 📦
2026-03-20 16:43:44 +00:00
A self-hosted, multi-protocol package registry built with Deno and TypeScript. Run your own private
**NPM**, **Docker/OCI ** , **Maven ** , **Cargo ** , **PyPI ** , **Composer ** , and **RubyGems ** registry —
all behind a single binary with a modern web UI.
2025-11-27 23:53:05 +00:00
## Issue Reporting and Security
2026-03-22 08:59:34 +00:00
For reporting bugs, issues, or security vulnerabilities, please visit [community.foss.global/ ](https://community.foss.global/ ). This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a [code.foss.global/ ](https://code.foss.global/ ) account to submit Pull Requests directly.
2025-11-27 23:53:05 +00:00
## ✨ Features
2026-03-20 16:43:44 +00:00
- 🔌 **7 Protocol Support ** — NPM, OCI/Docker, Maven, Cargo, PyPI, Composer, RubyGems via
[`@push.rocks/smartregistry` ](https://code.foss.global/push.rocks/smartregistry )
2026-03-20 13:56:43 +00:00
- 🏢 **Organizations & Teams ** — Hierarchical access control: orgs → teams → repositories
- 🔐 **Flexible Authentication ** — Local JWT auth, OAuth/OIDC, and LDAP with JIT user provisioning
- 🎫 **Scoped API Tokens ** — Per-protocol, per-scope tokens (`srg_` prefix) for CI/CD pipelines
- 🛡️ **RBAC Permissions ** — Reader → Developer → Maintainer → Admin per repository
- 🔍 **Upstream Caching ** — Transparently proxy and cache packages from public registries
- 📊 **Audit Logging ** — Full audit trail on every action for compliance
2026-03-22 08:59:34 +00:00
- 🎨 **Modern Web UI ** — Web Components dashboard built with [`@design.estate/dees-catalog` ](https://code.foss.global/design.estate/dees-catalog ), bundled into the binary
2026-03-20 13:56:43 +00:00
- ⚡ **Single Binary ** — Cross-compiled with `deno compile` for Linux and macOS (x64 + ARM64)
- 🗄️ **MongoDB + S3 ** — Metadata in MongoDB, artifacts in any S3-compatible store
2025-11-27 23:53:05 +00:00
## 🚀 Quick Start
### Prerequisites
- **MongoDB** >= 4.4
2026-03-20 13:56:43 +00:00
- **S3-compatible storage** (MinIO, AWS S3, Cloudflare R2, etc.)
2025-11-27 23:53:05 +00:00
2026-03-20 13:56:43 +00:00
### Install from Binary
2025-11-27 23:53:05 +00:00
```bash
2026-03-20 13:56:43 +00:00
# One-liner install (latest version)
curl -sSL https://code.foss.global/stack.gallery/registry/raw/branch/main/install.sh | sudo bash
# Install specific version
2026-03-22 08:59:34 +00:00
curl -sSL https://code.foss.global/stack.gallery/registry/raw/branch/main/install.sh | sudo bash -s -- --version v1.8.0
2026-03-20 13:56:43 +00:00
# Install + set up systemd service
curl -sSL https://code.foss.global/stack.gallery/registry/raw/branch/main/install.sh | sudo bash -s -- --setup-service
```
The installer:
2026-03-20 16:43:44 +00:00
2026-03-20 13:56:43 +00:00
- Detects your platform (Linux/macOS, x64/ARM64)
- Downloads the pre-compiled binary from Gitea releases
- Installs to `/opt/stack-gallery-registry/` with a symlink in `/usr/local/bin/`
- Optionally creates and enables a systemd service
### Run from Source
```bash
# Clone
2025-11-27 23:53:05 +00:00
git clone https://code.foss.global/stack.gallery/registry.git
cd registry
2026-03-22 08:59:34 +00:00
# Install Node dependencies (for tsbundle/tsdeno build tools)
pnpm install
2026-03-20 13:56:43 +00:00
# Development mode (hot reload, reads .nogit/env.json)
deno task dev
2025-11-27 23:53:05 +00:00
2026-03-20 13:56:43 +00:00
# Production mode
deno task start
2025-11-27 23:53:05 +00:00
```
2026-03-20 13:56:43 +00:00
The registry is available at `http://localhost:3000` .
## ⚙️ Configuration
2026-03-20 16:43:44 +00:00
Configuration is loaded from **environment variables ** (production) or from * * `.nogit/env.json` **
when using the `--ephemeral` flag (development).
| Variable | Default | Description |
| ----------------------- | --------------------------- | ------------------------------------------------------------ |
| `MONGODB_URL` | `mongodb://localhost:27017` | MongoDB connection string |
| `MONGODB_DB` | `stackgallery` | Database name |
| `S3_ENDPOINT` | `http://localhost:9000` | S3-compatible endpoint |
| `S3_ACCESS_KEY` | `minioadmin` | S3 access key |
| `S3_SECRET_KEY` | `minioadmin` | S3 secret key |
| `S3_BUCKET` | `registry` | S3 bucket name |
| `S3_REGION` | — | S3 region |
| `HOST` | `0.0.0.0` | Server bind address |
| `PORT` | `3000` | Server port |
| `JWT_SECRET` | `change-me-in-production` | JWT signing secret |
| `AUTH_ENCRYPTION_KEY` | _ (ephemeral) _ | 64-char hex for AES-256-GCM encryption of OAuth/LDAP secrets |
| `STORAGE_PATH` | `packages` | Base path in S3 for artifacts |
| `ENABLE_UPSTREAM_CACHE` | `true` | Cache packages from upstream registries |
| `UPSTREAM_CACHE_EXPIRY` | `24` | Cache TTL in hours |
2025-11-27 23:53:05 +00:00
2026-03-20 13:56:43 +00:00
**Example `.nogit/env.json` :**
2025-11-27 23:53:05 +00:00
```json
{
2026-03-20 13:56:43 +00:00
"MONGODB_URL": "mongodb://admin:pass@localhost:27017/stackregistry ?authSource=admin",
2025-11-27 23:53:05 +00:00
"MONGODB_NAME": "stackregistry",
"S3_HOST": "localhost",
"S3_PORT": "9000",
"S3_ACCESSKEY": "minioadmin",
"S3_SECRETKEY": "minioadmin",
"S3_BUCKET": "registry",
2026-03-20 13:56:43 +00:00
"S3_USESSL": false
2025-11-27 23:53:05 +00:00
}
```
2026-03-20 13:56:43 +00:00
## 🔌 Protocol Endpoints
2025-11-27 23:53:05 +00:00
2026-03-20 16:43:44 +00:00
Each protocol is handled natively via
[`@push.rocks/smartregistry` ](https://code.foss.global/push.rocks/smartregistry ). Point your package
manager at the registry:
2025-11-27 23:53:05 +00:00
2026-03-20 16:43:44 +00:00
| Protocol | Paths | Client Config Example |
| -------------- | --------------------------- | ------------------------------------------------------ |
2026-03-22 08:59:34 +00:00
| **NPM ** | `/-/npm/{org}/*` | `npm config set registry http://registry:3000/-/npm/myorg/` |
2026-03-20 16:43:44 +00:00
| **OCI/Docker ** | `/v2/*` | `docker login registry:3000` |
| **Maven ** | `/maven2/*` | Add repository URL in `pom.xml` |
| **Cargo ** | `/api/v1/crates/*` | Configure in `.cargo/config.toml` |
| **PyPI ** | `/simple/*` , `/pypi/*` | `pip install --index-url http://registry:3000/simple/` |
| **Composer ** | `/packages.json` , `/p/*` | Add repository in `composer.json` |
| **RubyGems ** | `/api/v1/gems/*` , `/gems/*` | `gem sources -a http://registry:3000` |
2025-11-27 23:53:05 +00:00
2026-03-20 16:43:44 +00:00
Authentication works with **Bearer tokens ** (API tokens prefixed `srg_` ) and **Basic auth **
(email:password or username:token).
2025-11-27 23:53:05 +00:00
2026-03-22 08:59:34 +00:00
### NPM Usage Example
```bash
# Configure npm to use your org's registry
npm config set @myorg:registry http://localhost:3000/-/npm/myorg/
# Authenticate
echo "//localhost:3000/-/npm/myorg/:_authToken=srg_YOUR_TOKEN" >> ~/.npmrc
# Publish & install as usual
npm publish
npm install @myorg/my -package
```
### Docker/OCI Usage Example
```bash
# Login
docker login localhost:3000
# Tag and push
docker tag myimage:latest localhost:3000/myorg/myimage:1.0.0
docker push localhost:3000/myorg/myimage:1.0.0
# Pull
docker pull localhost:3000/myorg/myimage:1.0.0
```
2026-03-20 13:56:43 +00:00
## 🔐 Authentication & Security
2025-11-27 23:53:05 +00:00
2026-03-20 13:56:43 +00:00
### Local Auth
2026-03-20 16:43:44 +00:00
2026-03-20 13:56:43 +00:00
- JWT-based with **15-minute access tokens ** and **7-day refresh tokens ** (HS256)
- Session tracking — each login creates a session, tokens embed session IDs
- Password hashing with PBKDF2 (10,000 rounds SHA-256 + random salt)
2025-11-27 23:53:05 +00:00
2026-03-20 13:56:43 +00:00
### External Auth (OAuth/OIDC & LDAP)
2026-03-20 16:43:44 +00:00
2026-03-20 13:56:43 +00:00
- **OAuth/OIDC** — Connect to any OIDC-compliant provider (Keycloak, Okta, Auth0, Azure AD, etc.)
- **LDAP** — Bind + search authentication against Active Directory or OpenLDAP
- **JIT Provisioning** — Users are auto-created on first external login
- **Auto-linking** — External identities are linked to existing users by email match
2026-03-20 16:43:44 +00:00
- **Encrypted secrets** — Provider client secrets and bind passwords are stored AES-256-GCM
encrypted
2025-11-27 23:53:05 +00:00
2026-03-20 13:56:43 +00:00
### RBAC Permissions
Access is resolved through a hierarchy:
2025-11-27 23:53:05 +00:00
```
2026-03-20 13:56:43 +00:00
Platform Admin (full access)
└─ Organization Owner/Admin
└─ Team Maintainer (read + write + delete on team repos)
└─ Team Member (read + write on team repos)
└─ Direct Repo Permission (reader / developer / maintainer / admin)
└─ Public Repository (read for everyone)
2025-11-27 23:53:05 +00:00
```
2026-03-20 13:56:43 +00:00
### Scoped API Tokens
Tokens are prefixed with `srg_` and can be scoped to:
2026-03-20 16:43:44 +00:00
2026-03-20 13:56:43 +00:00
- Specific **protocols ** (e.g., npm + oci only)
- Specific **actions ** (read / write / delete)
- Specific **organizations **
- Custom **expiration ** dates
2025-11-27 23:53:05 +00:00
2026-03-20 13:56:43 +00:00
## 📡 REST API
2025-11-27 23:53:05 +00:00
2026-03-20 16:43:44 +00:00
All management endpoints live under `/api/v1/` . Authenticated via
`Authorization: Bearer <jwt_or_api_token>` .
2026-03-20 13:56:43 +00:00
### Auth
2026-03-20 16:43:44 +00:00
| Method | Endpoint | Description |
| ------ | ---------------------------------- | ----------------------------------- |
| `POST` | `/api/v1/auth/login` | Login (email + password) |
| `POST` | `/api/v1/auth/refresh` | Refresh access token |
| `POST` | `/api/v1/auth/logout` | Logout (invalidate session) |
| `GET` | `/api/v1/auth/me` | Current user info |
| `GET` | `/api/v1/auth/providers` | List active external auth providers |
| `GET` | `/api/v1/auth/oauth/:id/authorize` | Initiate OAuth flow |
| `GET` | `/api/v1/auth/oauth/:id/callback` | OAuth callback |
| `POST` | `/api/v1/auth/ldap/:id/login` | LDAP login |
2025-11-27 23:53:05 +00:00
2026-03-20 13:56:43 +00:00
### Users
2026-03-20 16:43:44 +00:00
| Method | Endpoint | Description |
| -------- | ------------------- | ----------- |
| `GET` | `/api/v1/users` | List users |
| `POST` | `/api/v1/users` | Create user |
| `GET` | `/api/v1/users/:id` | Get user |
| `PUT` | `/api/v1/users/:id` | Update user |
2026-03-20 13:56:43 +00:00
| `DELETE` | `/api/v1/users/:id` | Delete user |
2025-11-27 23:53:05 +00:00
2026-03-20 13:56:43 +00:00
### Organizations
2026-03-20 16:43:44 +00:00
| Method | Endpoint | Description |
| -------- | ------------------------------------------- | ------------------- |
| `GET` | `/api/v1/organizations` | List organizations |
| `POST` | `/api/v1/organizations` | Create organization |
| `GET` | `/api/v1/organizations/:id` | Get organization |
| `PUT` | `/api/v1/organizations/:id` | Update organization |
| `DELETE` | `/api/v1/organizations/:id` | Delete organization |
| `GET` | `/api/v1/organizations/:id/members` | List members |
| `POST` | `/api/v1/organizations/:id/members` | Add member |
| `PUT` | `/api/v1/organizations/:id/members/:userId` | Update member role |
| `DELETE` | `/api/v1/organizations/:id/members/:userId` | Remove member |
2025-11-27 23:53:05 +00:00
### Repositories
2026-03-20 16:43:44 +00:00
| Method | Endpoint | Description |
| -------- | ------------------------------------------- | -------------- |
| `GET` | `/api/v1/organizations/:orgId/repositories` | List org repos |
| `POST` | `/api/v1/organizations/:orgId/repositories` | Create repo |
| `GET` | `/api/v1/repositories/:id` | Get repo |
| `PUT` | `/api/v1/repositories/:id` | Update repo |
| `DELETE` | `/api/v1/repositories/:id` | Delete repo |
2025-11-27 23:53:05 +00:00
### Packages
2026-03-20 16:43:44 +00:00
| Method | Endpoint | Description |
| -------- | ---------------------------------------- | ------------------- |
| `GET` | `/api/v1/packages` | Search packages |
| `GET` | `/api/v1/packages/:id` | Get package details |
| `GET` | `/api/v1/packages/:id/versions` | List versions |
| `DELETE` | `/api/v1/packages/:id` | Delete package |
| `DELETE` | `/api/v1/packages/:id/versions/:version` | Delete version |
2025-11-27 23:53:05 +00:00
2026-03-20 13:56:43 +00:00
### Tokens
2026-03-20 16:43:44 +00:00
| Method | Endpoint | Description |
| -------- | -------------------- | ---------------- |
| `GET` | `/api/v1/tokens` | List your tokens |
| `POST` | `/api/v1/tokens` | Create token |
| `DELETE` | `/api/v1/tokens/:id` | Revoke token |
2025-11-27 23:53:05 +00:00
2026-03-20 13:56:43 +00:00
### Audit
2026-03-20 16:43:44 +00:00
| Method | Endpoint | Description |
| ------ | --------------- | ---------------- |
| `GET` | `/api/v1/audit` | Query audit logs |
2026-03-20 13:56:43 +00:00
### Admin (Platform Admins Only)
2026-03-20 16:43:44 +00:00
| Method | Endpoint | Description |
| -------- | --------------------------------------- | ------------------------ |
| `GET` | `/api/v1/admin/auth/providers` | List all auth providers |
| `POST` | `/api/v1/admin/auth/providers` | Create auth provider |
| `GET` | `/api/v1/admin/auth/providers/:id` | Get provider details |
| `PUT` | `/api/v1/admin/auth/providers/:id` | Update provider |
| `DELETE` | `/api/v1/admin/auth/providers/:id` | Disable provider |
| `POST` | `/api/v1/admin/auth/providers/:id/test` | Test provider connection |
| `GET` | `/api/v1/admin/auth/settings` | Get platform settings |
| `PUT` | `/api/v1/admin/auth/settings` | Update platform settings |
2026-03-20 13:56:43 +00:00
### Health Check
2026-03-20 16:43:44 +00:00
| Method | Endpoint | Description |
| ------ | ----------------------- | ------------------------------------------------ |
| `GET` | `/health` or `/healthz` | Returns JSON status of MongoDB, S3, and registry |
2025-11-27 23:53:05 +00:00
2026-03-20 13:56:43 +00:00
## 🏗️ Architecture
2025-11-27 23:53:05 +00:00
2026-03-20 13:56:43 +00:00
```
registry/
├── mod.ts # Deno entry point
├── deno.json # Deno config, tasks, imports
2026-03-22 08:59:34 +00:00
├── package.json # Node deps (tsbundle, tsdeno, tswatch)
2026-03-20 13:56:43 +00:00
├── npmextra.json # tsdeno compile targets & gitzone config
├── install.sh # Binary installer script
├── .gitea/workflows/ # CI release pipeline
├── ts/
│ ├── registry.ts # StackGalleryRegistry — main orchestrator
│ ├── cli.ts # CLI commands (smartcli)
│ ├── plugins.ts # Centralized dependency imports
│ ├── api/
│ │ ├── router.ts # REST API router with JWT/token auth
│ │ └── handlers/ # auth, user, org, repo, package, token, audit, oauth, admin
2026-03-22 08:59:34 +00:00
│ ├── opsserver/ # TypedRequest RPC handlers
2026-03-20 13:56:43 +00:00
│ ├── models/ # MongoDB models via @push .rocks/smartdata
│ │ ├── user.ts, organization.ts, team.ts
│ │ ├── repository.ts, package.ts
│ │ ├── apitoken.ts, session.ts, auditlog.ts
│ │ ├── auth.provider.ts, external.identity.ts, platform.settings.ts
│ │ └── * .member.ts, * .permission.ts
│ ├── services/ # Business logic
│ │ ├── auth.service.ts # JWT login/refresh/logout
│ │ ├── external.auth.service.ts # OAuth/OIDC & LDAP flows
│ │ ├── crypto.service.ts # AES-256-GCM encryption
│ │ ├── token.service.ts # API token CRUD
│ │ ├── permission.service.ts # RBAC resolution
│ │ └── audit.service.ts # Audit logging
│ ├── providers/ # smartregistry integration
│ │ ├── auth.provider.ts # IAuthProvider implementation
│ │ └── storage.provider.ts # IStorageHooks for quota/audit
│ └── interfaces/ # TypeScript interfaces & types
2026-03-22 08:59:34 +00:00
└── ts_interfaces/ # Shared API contract (TypedRequest interfaces)
├── data/ # Data types (auth, org, repo, package, token, audit, admin)
└── requests/ # Request/response interfaces for all API endpoints
2026-03-20 13:56:43 +00:00
```
2025-11-27 23:53:05 +00:00
## 🔧 Technology Stack
2026-03-22 08:59:34 +00:00
| Component | Technology |
| ----------------- | ----------------------------------------------------------------------------------------- |
| **Runtime ** | Deno 2.x |
| **Language ** | TypeScript (strict mode) |
| **Database ** | MongoDB via [`@push.rocks/smartdata` ](https://code.foss.global/push.rocks/smartdata ) |
| **Storage ** | S3 via [`@push.rocks/smartbucket` ](https://code.foss.global/push.rocks/smartbucket ) |
| **Registry Core ** | [`@push.rocks/smartregistry` ](https://code.foss.global/push.rocks/smartregistry ) |
| **Frontend ** | Web Components via [`@design.estate/dees-element` ](https://code.foss.global/design.estate/dees-element ) + [`@design.estate/dees-catalog` ](https://code.foss.global/design.estate/dees-catalog ) |
| **UI Build ** | [`@git.zone/tsbundle` ](https://code.foss.global/git.zone/tsbundle ) |
| **Auth ** | JWT (HS256) + OAuth/OIDC + LDAP |
| **Build ** | [`@git.zone/tsdeno` ](https://code.foss.global/git.zone/tsdeno ) cross-compilation |
| **CI/CD ** | Gitea Actions → binary releases |
2025-11-27 23:53:05 +00:00
2026-03-20 13:56:43 +00:00
## 🛠️ Development
2025-11-27 23:53:05 +00:00
2026-03-20 13:56:43 +00:00
### Commands
2025-11-27 23:53:05 +00:00
```bash
2026-03-20 13:56:43 +00:00
# Start dev server with hot reload (reads .nogit/env.json)
deno task dev
2025-11-27 23:53:05 +00:00
2026-03-20 13:56:43 +00:00
# Watch mode: backend + UI + bundler concurrently
pnpm run watch
2026-03-22 08:59:34 +00:00
# Build UI (web components via tsbundle)
deno task build-ui
2026-03-20 13:56:43 +00:00
# Cross-compile binaries for all platforms
deno task compile
# Type check / format / lint
deno task check
deno task fmt
deno task lint
# Run tests
deno task test # All tests
deno task test:unit # Unit tests only
deno task test:integration # Integration tests (requires running server)
deno task test:e2e # E2E tests (requires running server + services)
2025-11-27 23:53:05 +00:00
```
2026-03-20 13:56:43 +00:00
### Build & Release
Releases are automated via Gitea Actions (`.gitea/workflows/release.yml` ):
1. Push a `v*` tag
2026-03-22 08:59:34 +00:00
2. CI builds the Web Components UI via `tsbundle`
2026-03-20 16:43:44 +00:00
3. `tsdeno compile` produces binaries for 4 platforms (linux-x64, linux-arm64, macos-x64,
macos-arm64)
2026-03-20 13:56:43 +00:00
4. Binaries + SHA256 checksums are uploaded as Gitea release assets
Compile targets are configured in `npmextra.json` under `@git.zone/tsdeno` .
### Storage Layout
Artifacts are stored in S3 at:
```
2026-03-22 08:59:34 +00:00
{storagePath}/{protocol}/packages/{packageName}/{version}/{filename}
2026-03-20 13:56:43 +00:00
```
2026-03-22 08:59:34 +00:00
For example: `packages/npm/packages/@myorg/mypackage/mypackage-1.0.0.tgz`
2025-11-27 23:53:05 +00:00
## License and Legal Information
2026-03-22 08:59:34 +00:00
This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [LICENSE ](./LICENSE ) file.
2025-11-27 23:53:05 +00:00
2026-03-22 08:59:34 +00:00
**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
2025-11-27 23:53:05 +00:00
### Trademarks
2026-03-22 08:59:34 +00:00
This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH or third parties, and are not included within the scope of the MIT license granted herein.
2026-03-20 13:56:43 +00:00
2026-03-22 08:59:34 +00:00
Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines or the guidelines of the respective third-party owners, and any usage must be approved in writing. Third-party trademarks used herein are the property of their respective owners and used only in a descriptive manner, e.g. for an implementation of an API or similar.
2025-11-27 23:53:05 +00:00
### Company Information
2026-03-22 08:59:34 +00:00
Task Venture Capital GmbH
Registered at District Court Bremen HRB 35230 HB, Germany
2025-11-27 23:53:05 +00:00
2026-03-20 13:56:43 +00:00
For any legal inquiries or further information, please contact us via email at hello@task .vc.
2025-11-27 23:53:05 +00:00
2026-03-22 08:59:34 +00:00
By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.