mirror of
https://github.com/getnora-io/nora.git
synced 2026-04-12 06:50:31 +00:00
docs: add authentication guide, TLS setup, FSTEC builds docs
- Fix docker-compose.yml: use ghcr.io/getnora-io/nora:latest - Remove stale CHANGELOG.md.bak, add *.bak to .gitignore - README: authentication guide (htpasswd, API tokens, RBAC) - README: TLS/HTTPS section (reverse proxy, insecure-registries) - README: document Dockerfile.astra and Dockerfile.redos (FSTEC) - CHANGELOG: add 0.2.28 release notes
This commit is contained in:
127
README.md
127
README.md
@@ -86,6 +86,62 @@ npm config set registry http://localhost:4000/npm/
|
||||
npm publish
|
||||
```
|
||||
|
||||
## Authentication
|
||||
|
||||
NORA supports Basic Auth (htpasswd) and revocable API tokens with RBAC.
|
||||
|
||||
### Quick Setup
|
||||
|
||||
```bash
|
||||
# 1. Create htpasswd file with bcrypt
|
||||
htpasswd -cbB users.htpasswd admin yourpassword
|
||||
# Add more users:
|
||||
htpasswd -bB users.htpasswd ci-user ci-secret
|
||||
|
||||
# 2. Start NORA with auth enabled
|
||||
docker run -d -p 4000:4000 \
|
||||
-v nora-data:/data \
|
||||
-v ./users.htpasswd:/data/users.htpasswd \
|
||||
-e NORA_AUTH_ENABLED=true \
|
||||
ghcr.io/getnora-io/nora:latest
|
||||
|
||||
# 3. Verify
|
||||
curl -u admin:yourpassword http://localhost:4000/v2/_catalog
|
||||
```
|
||||
|
||||
### API Tokens (RBAC)
|
||||
|
||||
Tokens support three roles: `read`, `write`, `admin`.
|
||||
|
||||
```bash
|
||||
# Create a write token (30 days TTL)
|
||||
curl -s -X POST http://localhost:4000/api/tokens \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"username":"admin","password":"yourpassword","role":"write","ttl_days":90,"description":"CI/CD"}'
|
||||
|
||||
# Use token with Docker
|
||||
docker login localhost:4000 -u token -p nra_<token>
|
||||
|
||||
# Use token with curl
|
||||
curl -H "Authorization: Bearer nra_<token>" http://localhost:4000/v2/_catalog
|
||||
|
||||
# List tokens
|
||||
curl -s -X POST http://localhost:4000/api/tokens/list \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"username":"admin","password":"yourpassword"}'
|
||||
|
||||
# Revoke token by hash prefix
|
||||
curl -s -X POST http://localhost:4000/api/tokens/revoke \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"username":"admin","password":"yourpassword","hash_prefix":"<first 16 chars>"}'
|
||||
```
|
||||
|
||||
| Role | Pull/Read | Push/Write | Delete/Admin |
|
||||
|------|-----------|------------|--------------|
|
||||
| `read` | Yes | No | No |
|
||||
| `write` | Yes | Yes | No |
|
||||
| `admin` | Yes | Yes | Yes |
|
||||
|
||||
## CLI Commands
|
||||
|
||||
```bash
|
||||
@@ -166,6 +222,77 @@ clear_env = false
|
||||
| `/cargo/` | Cargo |
|
||||
| `/simple/` | PyPI |
|
||||
|
||||
## TLS / HTTPS
|
||||
|
||||
NORA serves plain HTTP by design. **TLS is intentionally not built into the binary** — this is a deliberate architectural decision:
|
||||
|
||||
- **Single responsibility**: NORA manages artifacts, not certificates. Embedding TLS means bundling Let's Encrypt clients, certificate renewal logic, ACME challenges, and custom CA support — all of which already exist in battle-tested tools.
|
||||
- **Operational simplicity**: One place for certificates (reverse proxy), not scattered across every service. When a cert expires, you fix it in one config — not in NORA, Grafana, GitLab, and every other service separately.
|
||||
- **Industry standard**: Docker Hub, GitHub Container Registry, AWS ECR, Harbor, Nexus — none of them terminate TLS in the registry process. A reverse proxy in front is the universal pattern.
|
||||
- **Zero-config internal use**: On trusted networks (lab, CI/CD), NORA works out of the box without generating self-signed certs or managing keystores.
|
||||
|
||||
### Production (recommended): reverse proxy with auto-TLS
|
||||
|
||||
```
|
||||
Client → Caddy/Nginx (HTTPS, port 443) → NORA (HTTP, port 4000)
|
||||
```
|
||||
|
||||
Caddy example:
|
||||
|
||||
```
|
||||
registry.example.com {
|
||||
reverse_proxy localhost:4000
|
||||
}
|
||||
```
|
||||
|
||||
Nginx example:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name registry.example.com;
|
||||
ssl_certificate /etc/letsencrypt/live/registry.example.com/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/registry.example.com/privkey.pem;
|
||||
client_max_body_size 0; # unlimited for large image pushes
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:4000;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Internal / Lab: insecure registry
|
||||
|
||||
If you run NORA without TLS (e.g., on a private network), configure Docker to trust it:
|
||||
|
||||
```json
|
||||
// /etc/docker/daemon.json
|
||||
{
|
||||
"insecure-registries": ["192.168.1.100:4000"]
|
||||
}
|
||||
```
|
||||
|
||||
Then restart Docker:
|
||||
|
||||
```bash
|
||||
sudo systemctl restart docker
|
||||
```
|
||||
|
||||
> **Note:** `insecure-registries` disables TLS verification for that host. Use only on trusted networks.
|
||||
|
||||
## FSTEC-Certified OS Builds
|
||||
|
||||
NORA provides dedicated Dockerfiles for Russian FSTEC-certified operating systems:
|
||||
|
||||
- `Dockerfile.astra` — Astra Linux SE (for government and defense sector)
|
||||
- `Dockerfile.redos` — RED OS (for enterprise and public sector)
|
||||
|
||||
Both use `scratch` base with statically-linked binary for minimal attack surface. Comments in each file show how to switch to official distro base images if required by your security policy.
|
||||
|
||||
These builds are published as `-astra` and `-redos` tagged images in GitHub Releases.
|
||||
|
||||
## Performance
|
||||
|
||||
| Metric | NORA | Nexus | JFrog |
|
||||
|
||||
Reference in New Issue
Block a user