Commit Graph

256 Commits

Author SHA1 Message Date
970374b4e2 chore: add clippy.toml, issue/PR templates, Helm OCI docs, logging env vars
- clippy.toml: cognitive-complexity=25, too-many-arguments=7
- Issue templates: bug report + feature request (YAML forms)
- PR template with checklist (fmt, clippy, test, unwrap, changelog)
- README: Helm OCI support documented, NORA_LOG_LEVEL/FORMAT env vars
- GitHub topic: helm-registry re-added (verified helm push/pull works)
2026-04-02 15:27:23 +03:00
7c8964f8fa fix(deps): update sha2 0.10→0.11, hmac 0.12→0.13 (#75)
Breaking API changes in digest crate ecosystem:
- sha2 digest returns Array instead of GenericArray
- Replace format!("{:x}", digest) with hex::encode(digest)
- Add digest::KeyInit trait import for Hmac
- Update all hash formatting in docker, npm, s3, tokens
2026-03-31 19:36:29 +00:00
dependabot[bot]
d6e3f3e129 chore(deps): bump uuid from 1.22.0 to 1.23.0 (#69)
Bumps [uuid](https://github.com/uuid-rs/uuid) from 1.22.0 to 1.23.0.
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/v1.22.0...v1.23.0)

---
updated-dependencies:
- dependency-name: uuid
  dependency-version: 1.23.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: DevITWay | Pavel Volkov <devitway@gmail.com>
2026-03-31 19:05:56 +00:00
dependabot[bot]
4df4aacc32 chore(deps): bump schneegans/dynamic-badges-action from 1.7.0 to 1.8.0 (#67)
Bumps [schneegans/dynamic-badges-action](https://github.com/schneegans/dynamic-badges-action) from 1.7.0 to 1.8.0.
- [Release notes](https://github.com/schneegans/dynamic-badges-action/releases)
- [Changelog](https://github.com/Schneegans/dynamic-badges-action/blob/master/changelog.md)
- [Commits](e9a478b161...0e50b8bad3)

---
updated-dependencies:
- dependency-name: schneegans/dynamic-badges-action
  dependency-version: 1.8.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: DevITWay | Pavel Volkov <devitway@gmail.com>
2026-03-31 19:03:26 +00:00
8dcdc34476 docs: add CHANGELOG entry for v0.3.0 (#74)
Covers all changes since v0.2.35: Go proxy, Argon2id tokens,
config validation, code quality hardening, integration tests.
2026-03-31 18:52:52 +00:00
06e9ba4262 fix: add config validation at startup (#73)
Validate configuration after loading and env overrides:
- Error (panic): port=0, empty storage path (local), empty S3 bucket
- Warning (log): rate limit values=0, body_limit=0

Prevents confusing runtime errors from invalid config.
12 new unit tests for all validation branches.
2026-03-31 21:46:08 +03:00
bb125db074 fix: code quality hardening — unwrap removal, unsafe forbid, Go/Raw tests (#72)
* fix: remove unwrap() from production code, improve error handling

- Replace unwrap() with proper error handling in npm, mirror, validation
- Add input validation to cargo registry (crate name + version)
- Improve expect() messages with descriptive context in metrics, rate_limit
- Remove unnecessary clone() in error.rs, docker.rs, npm.rs, dashboard_metrics
- Add #![deny(clippy::unwrap_used)] to prevent future unwrap in prod code
- Add let-else pattern for safer null checks in validation.rs

* docs: update SECURITY.md — add 0.3.x to supported versions

* security: forbid unsafe code at crate level

Add #![forbid(unsafe_code)] to both lib.rs and main.rs.
NORA has zero unsafe blocks — this prevents future additions
without removing the forbid attribute (stronger than deny).

* build: add rust-toolchain.toml, Dockerfile HEALTHCHECK

- Pin toolchain to stable with clippy + rustfmt components
- Add Docker HEALTHCHECK for standalone deployments (wget /health)

* test: add Go proxy and Raw registry integration tests

Go proxy tests: list, .info, .mod, @latest, path traversal, 404
Raw registry tests: upload/download, HEAD, 404, path traversal,
overwrite, delete, binary data (10KB)
2026-03-31 21:15:59 +03:00
9ec5fe526b docs: remove stale ROADMAP.md, roadmap is in README (#66) 2026-03-28 01:48:39 +03:00
62e4304145 docs: update roadmap — add Mirror CLI, remove enterprise features (#65) 2026-03-28 01:28:13 +03:00
14f41ec10c fix: add Raw to sidebar, update footer stats (32MB, 7 registries), fix badges (#64) 2026-03-27 23:08:48 +03:00
9bf6615a10 docs: remove downloads badge (#63) v0.3.0 2026-03-27 22:11:49 +03:00
5d1c07db51 docs: add Go module proxy support to README (#62)
* docs: add Go module proxy to README, update dashboard GIF

- Add Go Modules to supported registries table
- Add Go usage example (GOPROXY)
- Add Go config.toml example
- Add /go/ endpoint to endpoints table
- Update dashboard GIF with 6 registry cards in one row
- Fix registries count: 6 package registries

* feat(ui): add Raw storage to dashboard, sidebar, and list pages

- Raw Storage card on dashboard with file count and size
- Raw in sidebar navigation with file icon
- Raw list and detail pages (/ui/raw)
- Raw mount point in mount points table
- Grid updated to 7 columns for all registry cards
- README: 7 registries, add Go module proxy docs

* docs: add product badges (release, image size, downloads)
2026-03-27 22:01:41 +03:00
52b1459be9 chore: clean up .gitignore, remove unused entries (#61) 2026-03-27 21:34:56 +03:00
325f51822f release: v0.3.0 (#60)
* release: bump version to v0.3.0, update dashboard GIF

New features in v0.3.0:
- Go module proxy (GOPROXY protocol) with caching
- Go in dashboard UI (sidebar, list, detail pages)
- Compact registry cards (6 in one row)
- Updated icons (Cargo crate, Go text mark)
- .gitleaks.toml restored

* security: update .gitignore and remove stale files

* security: update .gitignore to block dev tooling and process files
2026-03-27 21:30:41 +03:00
c8dc141b2f feat: add Go module proxy (GOPROXY protocol) (#59)
* feat: add Go module proxy (GOPROXY protocol) (#47)

Implements caching proxy for Go modules with 5 standard endpoints:
- GET /go/{module}/@v/list — list versions
- GET /go/{module}/@v/{version}.info — version metadata
- GET /go/{module}/@v/{version}.mod — go.mod file
- GET /go/{module}/@v/{version}.zip — module zip
- GET /go/{module}/@latest — latest version info

Features:
- Module path encoding/decoding per Go spec (!x → X)
- Immutable caching (.info/.mod/.zip never overwritten)
- Mutable endpoints (@v/list, @latest) refreshed from upstream
- Configurable upstream (default: proxy.golang.org)
- Separate timeout for .zip downloads (default: 120s)
- Size limit for zips (default: 100MB)
- Path traversal protection
- Dashboard integration (stats, mount points, index)
- 25 unit tests (encoding, path splitting, safety, content-type)

Closes #47

* style: cargo fmt

* feat(ui): add Go pages, compact cards, fix icons

- Go in sidebar + list/detail pages with go get command
- Dashboard: fix fallback icon (was Docker whale for Go)
- Compact registry cards: lg:grid-cols-6, all 6 in one row
- Cargo icon: crate boxes instead of truck
- Go icon: stylized Go text (sidebar + dashboard)

* fix(go): URL-decode path + send encoded paths to upstream

Go client sends %21 for ! in module paths. Axum wildcard does not
auto-decode, so we percent-decode manually. Upstream proxy.golang.org
expects encoded paths (with !), not decoded uppercase.

Tested: full Pusk build (22 modules, 135MB cached) including
SherClockHolmes/webpush-go with triple uppercase encoding.

* style: cargo fmt
2026-03-27 21:16:00 +03:00
a09f83ffdb fix: restore .gitleaks.toml lost during merge (#58)
The file was created on security/scorecard-hardening branch but only
the ci.yml change was cherry-picked to main — the config file itself
was left behind. CI references --config .gitleaks.toml which caused
the Security job to fail.

Adds allowlist for test placeholder tokens (nra_00112233...) that
trigger generic-api-key false positives.
2026-03-27 21:01:45 +03:00
3fe483a3a9 test: add docker push/pull, npm install, and upstream timeout integration tests (#57)
- Docker: build→push→pull→verify digest (sha256 match)
- npm: real npm install via NORA registry, verify version and integrity hash
- Upstream: verify 404 returns quickly (no retry hang)
- All 3 new test blocks pass on local run
2026-03-25 02:08:16 +03:00
d909a62ac5 feat: upstream proxy retry + Maven proxy-only (#56)
* docs: add DCO, governance model, roles, vulnerability credit policy

* security: migrate token hashing from SHA256 to Argon2id

- Replace unsalted SHA256 with Argon2id (salted) for API token hashing
- Fix TOCTOU race: replace exists()+read() with read()+match on error
- Set chmod 600 on token files and 700 on token storage directory
- Auto-migrate legacy SHA256 tokens to Argon2id on first verification
- Add regression tests: argon2 format, legacy migration, file permissions

* feat: add retry with timeout for upstream proxy, mark Maven proxy-only

- Add shared proxy_fetch() and proxy_fetch_text() with 1 retry on 5xx/timeout
- Replace duplicated fetch_from_proxy in maven.rs, npm.rs, pypi.rs
- Mark Maven as proxy-only in README (no full repository manager support)
- Existing timeout config (30s maven/npm/pypi, 60s docker) preserved
- 4xx errors fail immediately without retry
2026-03-25 01:56:59 +03:00
432e8d35af security: migrate token hashing from SHA256 to Argon2id (#55)
* docs: add DCO, governance model, roles, vulnerability credit policy

* security: migrate token hashing from SHA256 to Argon2id

- Replace unsalted SHA256 with Argon2id (salted) for API token hashing
- Fix TOCTOU race: replace exists()+read() with read()+match on error
- Set chmod 600 on token files and 700 on token storage directory
- Auto-migrate legacy SHA256 tokens to Argon2id on first verification
- Add regression tests: argon2 format, legacy migration, file permissions
2026-03-24 22:56:43 +00:00
975264c353 fix(deps): update rustls-webpki 0.103.9 -> 0.103.10 (RUSTSEC-2026-0049)
Also revert codeql-action to tag pin in scorecard.yml —
scorecard webapp rejects SHA pins for this specific action.
2026-03-20 23:07:09 +00:00
533f3cd795 release: bump version to v0.2.35 2026-03-20 22:54:30 +00:00
8fc741c8db feat: add anonymous read mode (NORA_AUTH_ANONYMOUS_READ)
When auth is enabled with anonymous_read=true, GET/HEAD requests
are allowed without credentials (pull/download), while write
operations (PUT/POST/DELETE/PATCH) still require authentication.

Use case: public demo registries, read-only mirrors.

Config: NORA_AUTH_ANONYMOUS_READ=true or auth.anonymous_read=true
2026-03-20 22:48:41 +00:00
9709471485 fix: address code review findings
- Pin slsa-github-generator and codeql-action by SHA (not tag)
- Replace anonymous tuple with GroupedActivity struct for readability
- Replace unwrap() with if-let for safety
- Add warning message on attestation failure instead of silent || true
- Fix clippy: map_or -> is_some_and
2026-03-20 22:14:16 +00:00
2ec0fe4a28 release: bump version to v0.2.34 2026-03-20 19:46:42 +00:00
9f951ccc82 ui: fix table cell padding alignment
Add px-4 to all td cells in Mount Points and Activity tables
to match th header padding. Remove non-functional px-4 from
tbody elements (CSS padding does not apply to tbody).
2026-03-20 19:44:14 +00:00
f0cbb22bd9 fix(deps): update tar 0.4.44 -> 0.4.45
Fixes CVE-2026-33055 (PAX size header bypass) and
CVE-2026-33056 (symlink chmod directory traversal).
2026-03-20 19:32:46 +00:00
ceb75e0ce3 ui: group consecutive identical activity entries
Repeated cache hits for the same artifact now show as
"artifact (x4)" instead of 4 identical rows.
Reduces visual noise in dashboard activity log.
2026-03-20 19:23:41 +00:00
58d14a820e docs: remove hardcoded scorecard version from README 2026-03-20 11:35:14 +00:00
ef5f4e52c3 docs: restructure README for conversion
- Move badges from top to Security & Trust section
- Add dashboard GIF (EN/RU crossfade) as first visual
- Add "Why NORA" section with key differentiators
- Add "Used by" production reference
- Add binary install option
- Add Supported Registries table with mount points
- Streamline features into scannable list
- Remove emoji from footer
- Add comparison link placeholder
2026-03-20 11:25:32 +00:00
35e930295c test: add 82 unit tests across 7 modules
Coverage targets:
- activity_log: ActionType display, ActivityLog push/recent/all/bounded
- audit: AuditEntry, AuditLog write/read with tempdir
- config: defaults for all sub-configs, env overrides, TOML parsing
- dashboard_metrics: record_download/upload, cache_hit_rate, persistence
- error: constructors, Display, IntoResponse for all variants
- metrics: detect_registry for all protocol paths
- repo_index: paginate, RegistryIndex basics, RepoIndex invalidate

Total tests: 103 -> 185
2026-03-20 10:08:49 +00:00
3246bd9ffd ci: add test coverage with tarpaulin and dynamic badge via gist 2026-03-20 09:32:22 +00:00
cfa6a4d0ed chore: remove internal QA scripts from public repo 2026-03-19 12:42:53 +00:00
79fa8e0d4a chore: add CODEOWNERS, CHANGELOG v0.2.33, SLSA provenance, QA scripts 2026-03-19 12:39:58 +00:00
b23765bebd fix: update cosign-installer SHA to v3.8.0 2026-03-19 11:42:53 +00:00
b91c5531b6 release: bump version to v0.2.33 (#46) 2026-03-19 11:41:06 +00:00
596b18a3fa release: bump version to v0.2.33 2026-03-19 11:08:51 +00:00
07aed45518 fix: use tag for codeql-action in scorecard (webapp rejects SHA pins) 2026-03-19 10:42:14 +00:00
4ec963d41c fix: add repo_token and permissions to scorecard workflow 2026-03-19 10:35:57 +00:00
7f7e3e4986 fix: revert scorecard-action to tag (Docker action incompatible with SHA pin) 2026-03-19 10:33:27 +00:00
d51f176fd8 fix: use commit SHA for scorecard-action (not tag SHA) 2026-03-19 09:21:29 +00:00
34d30433cb fix: correct scorecard-action SHA pin for v2.4.3 2026-03-19 09:19:41 +00:00
a6db016d7d ci: retrigger scorecard workflow 2026-03-19 09:18:00 +00:00
fbd2aa35e8 ci: improve OpenSSF Scorecard rating (#45)
- Add CodeQL workflow for SAST analysis (Actions language)
- Pin scorecard-action and codeql-action by SHA in scorecard.yml
- Add cargo-audit SARIF upload for security tab integration
2026-03-19 11:51:11 +03:00
fa2cd45ed3 security: harden Docker registry and container runtime
- Verify blob digest (SHA256) on upload, reject mismatches (DIGEST_INVALID)
- Reject sha512 digests (only sha256 supported)
- Add upload session limits: max 100 concurrent, 2GB per session, 30min TTL
- Bind upload sessions to repository name (prevent session fixation)
- Filter .meta.json from Docker tag list (fix ArgoCD Image Updater recursion)
- Fix catalog to show namespaced images (library/alpine instead of library)
- Add security headers: CSP, X-Frame-Options, X-Content-Type-Options, Referrer-Policy
- Run containers as non-root user (USER nora) in all 3 Dockerfiles
- Add configurable NORA_MAX_UPLOAD_SESSIONS and NORA_MAX_UPLOAD_SESSION_SIZE_MB
2026-03-19 08:29:28 +00:00
f76dab1184 fix: pin ClusterFuzzLite base image by SHA, fix Docker tag double-suffix 2026-03-18 13:20:35 +00:00
e6043a6e2f fix: use project gitleaks config in CI, relax rules for documentation examples 2026-03-18 12:48:05 +00:00
54a08153f1 docs: add public roadmap, cosign verification in install script 2026-03-18 12:36:51 +00:00
a36287a627 community: add issue/PR templates, code of conduct, update contributing guide 2026-03-18 12:22:10 +00:00
eb1b8db01e chore: remove unused crates and demo traffic scripts
- Remove nora-cli (unimplemented stub)
- Remove nora-storage (standalone S3 server, not used)
- Remove demo traffic generator and systemd service
2026-03-18 12:19:58 +00:00
58f98949e4 style: clean up code comments 2026-03-18 11:23:11 +00:00