-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathllms.txt
More file actions
115 lines (79 loc) · 4.24 KB
/
Copy pathllms.txt
File metadata and controls
115 lines (79 loc) · 4.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# trupu
> Trusted Publishing for Docker registries using GitHub Actions OIDC.
trupu is an authentication server that enables passwordless Docker image pushes from GitHub Actions to a self-hosted Docker registry. It uses OpenID Connect (OIDC) tokens instead of long-lived credentials, implementing the OpenSSF Trusted Publishers standard.
## Architecture
GitHub Actions → Traefik (ForwardAuth) → trupu (/auth) → Docker Registry
- Traefik intercepts every request to the registry and forwards it to trupu's /auth endpoint
- trupu verifies the GitHub OIDC JWT against GitHub's JWKS
- On success, the request is proxied to the registry
- On failure, 401/403 is returned
## Project structure
This is a pnpm monorepo with two packages:
- packages/server — The Hono-based auth server (published as @trupu/server on npm and ghcr.io/nmerget/trupu on Docker)
- packages/docs — Astro Starlight documentation site (deployed to GitHub Pages)
## Server
The server is built with Hono on Node.js. It uses esbuild to bundle into a single minified file (~54kb).
### Key files
- src/index.ts — Entry point, wires provider + app + serve()
- src/app.ts — createApp(provider, config) factory, decoupled from serve() for testability
- src/config.ts — General server config (PORT, DEV_MODE, DEV_TOKEN)
- src/provider/types.ts — Provider interface and VerifiedIdentity type
- src/provider/github/config.ts — GitHub-specific config (ALLOWED_PUBLISHERS, ALLOWED_REFS, OIDC_AUDIENCE), parsePublishers()
- src/provider/github/index.ts — createGitHubProvider(), extractWorkflow(), matchRef()
### Provider interface
```typescript
interface VerifiedIdentity {
repository: string;
workflow: string;
ref: string;
}
interface Provider {
verifyToken(token: string): Promise<VerifiedIdentity>;
}
```
The provider pattern allows adding new CI providers (e.g. GitLab) by implementing this interface in a new provider/ subdirectory.
### Endpoints
- GET /auth — Traefik ForwardAuth endpoint. Accepts Bearer (OIDC token) and Basic (docker login) auth schemes. Returns 200 with identity headers, 401 with Www-Authenticate challenge, or 403 on invalid token.
- GET /healthz — Health check, returns { status: "ok" }
### Trusted publisher format
Publishers are configured as `owner/repo:workflow.yml` via the ALLOWED_PUBLISHERS environment variable. The workflow filename is extracted from the GitHub OIDC token's `job_workflow_ref` claim.
### Ref matching
ALLOWED_REFS supports exact matches and trailing wildcard patterns (e.g. `refs/tags/v*` matches `refs/tags/v1.0.0`).
## Environment variables
- PORT (default: 3000) — Server port
- DEV_MODE (default: false) — Skip OIDC verification, accept DEV_TOKEN
- DEV_TOKEN (default: trupu-dev-token) — Static token for dev mode
- ALLOWED_PUBLISHERS — Comma-separated owner/repo:workflow.yml entries
- ALLOWED_REFS — Comma-separated ref patterns (supports trailing *)
- OIDC_AUDIENCE (default: https://registry.example.com) — Expected aud claim
## Docker Compose files
- docker-compose.yml — Local development with bundled Traefik (file provider)
- docker-compose.dev.yml — Dev override enabling DEV_MODE and Traefik dashboard
- docker-compose.dokploy.yml — Production deployment on Dokploy (uses Docker labels, external dokploy-network)
## Testing
Tests use vitest with mock providers. 23 tests covering:
- Auth endpoint (Bearer, Basic, missing auth, dev mode)
- GitHub provider (parsePublishers, extractWorkflow, matchRef)
Run: `pnpm test`
## CI/CD
GitHub Actions workflow (.github/workflows/default.yml):
- ci — lint, format:check, test, build
- deploy — Astro docs to GitHub Pages
- release — Changesets version + npm publish with provenance
- publish-docker — Build and push Docker image to ghcr.io
Permissions follow least privilege: read-only default, elevated per job.
## Tech stack
- Runtime: Node.js 24
- Framework: Hono + @hono/node-server
- OIDC: jose (JWT verification via JWKS)
- Bundler: esbuild (single-file minified output)
- Tests: vitest
- Docs: Astro Starlight
- Package manager: pnpm
- Linting: eslint + typescript-eslint
- Formatting: prettier
## Links
- Documentation: https://nmerget.github.io/trupu/
- npm: https://www.npmjs.com/package/@trupu/server
- Docker: ghcr.io/nmerget/trupu
- GitHub: https://github.com/nmerget/trupu