Аутентификация
NORA поддерживает аутентификацию на основе htpasswd с API-токенами для программного доступа. Аутентификация отключена по умолчанию и должна быть включена явно.
Включение аутентификации
Заголовок раздела «Включение аутентификации»Установите переменную окружения NORA_AUTH_ENABLED или настройте её в config.toml:
# Environment variableexport NORA_AUTH_ENABLED=true[auth]enabled = truehtpasswd_file = "users.htpasswd"token_storage = "data/tokens"Настройка htpasswd
Заголовок раздела «Настройка htpasswd»NORA использует Apache-совместимые файлы htpasswd для управления пользователями. Создайте файл паролей с помощью htpasswd (из пакета apache2-utils) или любого совместимого инструмента:
Создание файла htpasswd
Заголовок раздела «Создание файла htpasswd»# Install htpasswd (Debian/Ubuntu)apt-get install apache2-utils
# Create file with first userhtpasswd -Bc users.htpasswd admin
# Add additional usershtpasswd -B users.htpasswd developerhtpasswd -B users.htpasswd ci-botФлаг -B использует хеширование bcrypt, что является рекомендуемым алгоритмом.
Монтирование файла
Заголовок раздела «Монтирование файла»Docker:
docker run -d \ --name nora \ -p 4000:4000 \ -v /data/nora:/data \ -v /etc/nora/users.htpasswd:/app/users.htpasswd:ro \ -e NORA_AUTH_ENABLED=true \ -e NORA_AUTH_HTPASSWD_FILE=/app/users.htpasswd \ ghcr.io/getnora-io/nora:latestKubernetes:
apiVersion: v1kind: Secretmetadata: name: nora-htpasswdtype: OpaquestringData: users.htpasswd: | admin:$2y$05$... ci-bot:$2y$05$...---apiVersion: apps/v1kind: Deploymentmetadata: name: noraspec: template: spec: containers: - name: nora env: - name: NORA_AUTH_ENABLED value: "true" - name: NORA_AUTH_HTPASSWD_FILE value: /etc/nora/users.htpasswd volumeMounts: - name: htpasswd mountPath: /etc/nora readOnly: true volumes: - name: htpasswd secret: secretName: nora-htpasswdРежим анонимного чтения
Заголовок раздела «Режим анонимного чтения»Когда NORA_AUTH_ANONYMOUS_READ=true, неаутентифицированные пользователи могут скачивать артефакты (pull), но аутентификация по-прежнему требуется для операций загрузки (push).
export NORA_AUTH_ENABLED=trueexport NORA_AUTH_ANONYMOUS_READ=true[auth]enabled = trueanonymous_read = trueЭто полезно для организаций, которые хотят обеспечить открытый доступ на чтение (например, для общих библиотек), ограничивая при этом круг лиц, имеющих право публиковать артефакты.
| Операция | Анонимное чтение = false | Анонимное чтение = true |
|---|---|---|
| Pull / Скачивание | Требуется аутентификация | Аутентификация не нужна |
| Push / Загрузка | Требуется аутентификация | Требуется аутентификация |
| Удаление / Администрирование | Требуется аутентификация | Требуется аутентификация |
API-токены
Заголовок раздела «API-токены»API-токены обеспечивают программный доступ без раскрытия учётных данных htpasswd. Токены имеют префикс nra_ для удобной идентификации и используют хеширование Argon2.
Роли токенов
Заголовок раздела «Роли токенов»| Роль | Разрешения |
|---|---|
read | Только скачивание артефактов |
write | Скачивание, публикация и загрузка артефактов |
admin | Полный доступ, включая управление токенами |
Создание токена
Заголовок раздела «Создание токена»curl -X POST http://localhost:4000/api/tokens \ -H "Content-Type: application/json" \ -d '{ "username": "admin", "password": "your-password", "role": "write", "ttl_days": 90, "description": "CI/CD pipeline token" }'Ответ:
{ "token": "nra_a1b2c3d4e5f6...", "expires_in_days": 90}Сохраните значение токена немедленно — оно показывается только один раз при создании.
Просмотр списка токенов
Заголовок раздела «Просмотр списка токенов»curl -X POST http://localhost:4000/api/tokens/list \ -H "Content-Type: application/json" \ -d '{ "username": "admin", "password": "your-password" }'Ответ:
{ "tokens": [ { "hash_prefix": "a1b2c3", "created_at": 1714200000, "expires_at": 1721976000, "last_used": 1714300000, "description": "CI/CD pipeline token", "role": "write" } ]}Отзыв токена
Заголовок раздела «Отзыв токена»Используйте hash_prefix из ответа на запрос списка:
curl -X POST http://localhost:4000/api/tokens/revoke \ -H "Content-Type: application/json" \ -d '{ "username": "admin", "password": "your-password", "hash_prefix": "a1b2c3" }'Вход в Docker
Заголовок раздела «Вход в Docker»NORA поддерживает стандартную аутентификацию Docker. Когда аутентификация включена, используйте docker login перед операциями push/pull:
# Login with htpasswd credentialsdocker login localhost:4000# Username: admin# Password: ****
# Login with API token (use token as password, any username)docker login localhost:4000 -u token -p nra_a1b2c3d4e5f6...Для автоматизированных процессов используйте --password-stdin:
echo "nra_a1b2c3d4e5f6..." | docker login localhost:4000 -u token --password-stdinИнтеграция с CI/CD
Заголовок раздела «Интеграция с CI/CD»GitHub Actions
Заголовок раздела «GitHub Actions»name: Build and Pushon: push: branches: [main]
jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
- name: Login to NORA run: | echo "${{ secrets.NORA_TOKEN }}" | \ docker login registry.example.com -u token --password-stdin
- name: Build and Push run: | docker build -t registry.example.com/myapp:${{ github.sha }} . docker push registry.example.com/myapp:${{ github.sha }}Для реестров, отличных от Docker (npm, PyPI, Cargo и др.), используйте токен в соответствующей конфигурации клиента:
# npm - name: Publish npm package env: NORA_TOKEN: ${{ secrets.NORA_TOKEN }} run: | echo "//registry.example.com/:_authToken=${NORA_TOKEN}" > .npmrc npm publish --registry=https://registry.example.com
# PyPI (twine) - name: Publish Python package env: NORA_TOKEN: ${{ secrets.NORA_TOKEN }} run: | twine upload --repository-url https://registry.example.com/pypi/ \ -u token -p "${NORA_TOKEN}" dist/*GitLab CI
Заголовок раздела «GitLab CI»stages: - build - publish
variables: NORA_REGISTRY: registry.example.com
build: stage: build image: docker:latest services: - docker:dind before_script: - echo "$NORA_TOKEN" | docker login $NORA_REGISTRY -u token --password-stdin script: - docker build -t $NORA_REGISTRY/myapp:$CI_COMMIT_SHA . - docker push $NORA_REGISTRY/myapp:$CI_COMMIT_SHA
publish-maven: stage: publish image: maven:3.9 script: - > mvn deploy -DaltDeploymentRepository=nora::https://${NORA_REGISTRY}/maven2 -Dserver.username=token -Dserver.password=${NORA_TOKEN}Сохраните NORA_TOKEN как маскированную CI/CD-переменную в настройках проекта GitLab.
Лучшие практики безопасности токенов
Заголовок раздела «Лучшие практики безопасности токенов»- Используйте токены с ограниченными правами. Создавайте токены
readдля рабочих нагрузок, которым нужен только pull, и токеныwriteтолько для пайплайнов, публикующих артефакты. - Устанавливайте TTL. Всегда указывайте
ttl_daysпри создании токенов. Регулярно выполняйте ротацию токенов. - Не коммитьте токены. Используйте секреты CI/CD (GitHub Secrets, GitLab CI Variables) для передачи токенов во время выполнения.
- Отзывайте при компрометации. Если токен утёк, немедленно отзовите его через API.
- Используйте анонимное чтение, когда возможно. Если ваши артефакты не являются конфиденциальными, включите
NORA_AUTH_ANONYMOUS_READ=trueдля снижения нагрузки по управлению токенами.
Смотрите также
Заголовок раздела «Смотрите также»- Справочник по конфигурации — все переменные окружения
- Курирование — контроль доступа к пакетам
- Развёртывание в продакшене — настройка TLS и прокси