Skip to content

Latest commit

 

History

1,229 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Drydock

Drydock reviews package artifacts before a maintainer approves publication. It compares the candidate with a tag-aware published baseline, runs deterministic supply-chain checks, optionally sends changed-file evidence to Cloudflare Workers AI, and saves a review report.

Approval stays outside Drydock: maintainers approve in npm, npmjs.com, or GitHub with their own required 2FA/review step. Drydock never publishes and never collects approval codes.

Drydock runs as a hosted service at drydock.org; this repository is its source, and it can be self-hosted on your own Cloudflare account. To add it to a release, jump to Add Drydock to your release.

Sponsored by

Aikido Security

Aikido Security sponsors Drydock's development. Sponsorship funds the work; it does not influence detection rules, findings, or risk scoring.

Source code is built into a package, staged as a release, held in Drydock quarantine where a scan of @acme/cli 4.2.0 to 4.3.0 reports 1 critical and 2 medium findings, and blocked from becoming a published package

Add Drydock to your release

If you publish from GitHub Actions, use a workflow gate. It is the path for npm, PyPI, and VS Code alike, and it is what the example repositories below use. npm stage publish is a shortcut for npm maintainers who already publish that way from a terminal — if you don't, skip it. Both paths produce the same review report; they differ only in who holds the candidate while you read it.

Workflow gate — GitHub Actions publishes (npm, PyPI, VS Code)

CI builds the release and uploads it. A GitHub Environment pauses the publish job until you accept the review in Drydock, then the same job publishes the exact reviewed bytes.

  1. Sign in at drydock.org and create the organization that owns the release.

  2. In Organization settings → GitHub App, install the Drydock GitHub App on the account that hosts the repository.

  3. In the repository's Settings → Environments, create an environment (for example production) and enable Drydock as a custom deployment protection rule.

  4. Back in Drydock settings, map that repository and environment to your organization.

  5. Split your release workflow into a build job that uploads the artifacts and a publish job pinned to the protected environment:

    jobs:
      pack:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          - run: npm ci
          - run: npm pack --pack-destination dist
          - run: cd dist && sha256sum *.tgz > SHA256SUMS
          - uses: actions/upload-artifact@v4
            with:
              name: npm-release-candidates
              path: dist/
    
      publish:
        needs: pack
        environment: production # Drydock holds this job
        permissions: { id-token: write, contents: read }
        steps:
          - uses: actions/download-artifact@v4
            with: { name: npm-release-candidates, path: dist }
          - run: cd dist && sha256sum --check --strict SHA256SUMS
          - run: npm publish dist/*.tgz --access public --provenance
  6. Push a release. The publish job pauses, Drydock reviews the uploaded artifacts, and accepting the review releases the job. Rejecting it fails the release closed.

There is no Drydock manifest to maintain: package name, version, and ecosystem are read from metadata inside the uploaded .tgz, .whl, .tar.gz, or .vsix. A monorepo upload becomes one report per package, and the job continues only once every package is accepted. The publish job must publish the bytes it downloaded — rebuilding after approval breaks the review boundary, which is what the SHA256SUMS record/check pair enforces.

Full workflows for each ecosystem: PyPI CI example, npm monorepo CI example, and docs/workflow-gates.md.

npm stage publish — npm only, no CI changes

npm holds a private staged tarball; Drydock reviews it and you finish the publish in npm with your own 2FA.

  1. Create a Drydock organization, then on npmjs.com generate a granular access token with Packages and scopes: Read-only and Organizations: No access covering the scopes you publish.
  2. Paste it into Organization settings → npm access.
  3. Run npm stage publish from the package directory. Drydock discovers the stage, scans it, and shows the report.
  4. Record your decision in Drydock, then complete or discard the publish on npm — on npmjs.com or with the npm stage approve / npm stage reject command Drydock shows you.

The longer walkthrough of both paths — what the report contains, how the credential boundary works, and per-ecosystem workflow examples — lives at drydock.org/docs.

Docs

drydock.org/docs is the guide for maintainers setting Drydock up. The files below are the engineering and operator reference for working on Drydock or self-hosting it; start with docs/README.md to pick the smallest relevant one. Common entry points:

Layout

server/       Hono Worker, scan pipeline, adapters, persistence, webhooks
src/          Preact UI and typed API models
drizzle/      D1 migrations
docs/         Architecture, security, workflow, setup, and test references
test/         Vitest, Worker-runtime, security corpus, and fake-registry e2e

Develop

Requirements: Node 22.14.0+ and pnpm 11.1.1 (pinned in package.json).

pnpm install
cp .dev.vars.example .dev.vars
pnpm run dev

The dev server runs the Worker and UI through Vite at http://localhost:5173. Edit .dev.vars with local Cloudflare, Better Auth, npm, GitHub App, Slack, and optional Workers AI/Flagship values as described in docs/self-hosting.md.

Useful commands:

pnpm run lint
pnpm run format:check
pnpm run typecheck
pnpm run test
pnpm run test:e2e
pnpm run verify

For deterministic browser testing without real staged publishes, use the local fake-registry harness in docs/e2e-test-environment.md. For an agent-readable product walkthrough, use docs/agent-tour.md.

Configuration

The checked-in wrangler.jsonc describes the maintainers' deployment. Self-hosters copy docs/examples/wrangler.self-host.jsonc to the gitignored wrangler.self-host.jsonc, pass it explicitly to Vite, migrations, and secret commands, then deploy the config generated by the Vite build. See docs/self-hosting.md for the complete flow.

Core Cloudflare bindings are D1 (DB), the Dynamic Worker loader (LOADER), and Workers AI (AI). Queue (SCAN_QUEUE), R2 (ARTIFACTS), KV (COMPARE_CACHE), Flagship (FLAGS), Analytics Engine (PRODUCT_ANALYTICS), email (SEND_EMAIL), and static assets (ASSETS) support the corresponding optional or deployed features.

Important secrets/vars:

  • BETTER_AUTH_SECRET, BETTER_AUTH_URL
  • NPM_CONNECTIONS_ENCRYPTION_KEY
  • GITHUB_APP_ID, GITHUB_APP_SLUG, GITHUB_APP_CLIENT_ID, GITHUB_APP_CLIENT_SECRET, GITHUB_APP_PRIVATE_KEY, GITHUB_APP_WEBHOOK_SECRET, and optional GITHUB_APP_STATE_SECRET
  • SLACK_CLIENT_ID, SLACK_CLIENT_SECRET

Run pnpm run cf-typegen after changing Cloudflare bindings.

API surface

The authenticated JSON API lives under /api/v1. The main resources are:

  • scans: create/list/read/export reports, compare published baselines, and fetch prior file samples;
  • npm connection: read public metadata, store/rotate, validate, and remove the current organization token;
  • release targets and workflow gates: map GitHub repositories/environments, review queued gate artifacts, and post accept/reject decisions;
  • auth/org/settings helpers for Better Auth-backed sessions and organization membership.

Consult route definitions under server/routes/ for exact request/response shapes; shared types are imported by the UI from server/.

Security posture

  • Package artifacts are untrusted evidence and are never executed.
  • npm credentials are encrypted at rest, decrypted only for registry access, and never passed into the Dynamic Worker sandbox.
  • The sandbox can fetch only through constrained brokers/gateways and returns bounded metadata/text evidence.
  • AI review is advisory and on by default behind the ai-review killswitch, and cannot downgrade deterministic findings.
  • Raw tarballs are not retained by default; persisted reports use redacted summaries and canonical report JSON.

See docs/security-model.md for the full contract.

License

Drydock is open-source software released under the Apache License 2.0.

About

Review the artifact before you publish it: diffs the built npm/PyPI package against the last published version and pins risk signals to the changed lines

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

20 stars

Watchers

1 watching

Forks

Contributors

Languages