Skip to content

Référence API — APT Repo Manager

Table des matières

  1. Authentification
  2. Codes de réponse standard
  3. Endpoints par module
  4. Auth
  5. Packages
  6. Upload
  7. Import
  8. Sécurité
  9. SBOM
  10. Téléchargements
  11. Dashboard
  12. Distributions
  13. Paramètres
  14. Santé
  15. Exemples complets
  16. Intégration CI/CD
  17. Limites et rate limiting

Authentification

JWT (sessions interactives)

La majorité des endpoints requiert un token JWT transmis dans l'en-tête HTTP Authorization.

Obtenir un token :

TOKEN=$(curl -s -X POST http://localhost:8000/auth/token \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"Admin1234!"}' | jq -r .access_token)

Utiliser le token :

curl -H "Authorization: Bearer $TOKEN" http://localhost:8000/packages/

API Tokens (CI/CD)

Pour les pipelines automatisés, utilisez un API token permanent au format repod_xxxxxxxxxx :

Authorization: Bearer repod_xxxxxxxxxx

Les API tokens sont créés et gérés via les endpoints /auth/api-tokens (réservé aux admins).

Endpoints publics (sans authentification)

Les endpoints suivants sont accessibles sans token :

Endpoint Description
POST /auth/token Connexion / obtention du JWT
POST /auth/forgot-password Demande de réinitialisation de mot de passe
POST /auth/reset-password Réinitialisation avec token reçu par e-mail
GET /health Bilan de santé complet
GET /health/live Sonde de vivacité
GET /health/ready Sonde de disponibilité

Codes de réponse standard

Code Signification
200 OK Requête traitée avec succès
201 Created Ressource créée avec succès
204 No Content Succès sans corps de réponse
400 Bad Request Paramètres ou corps de requête invalides
401 Unauthorized Token absent, invalide ou expiré
403 Forbidden Rôle insuffisant pour cette action
404 Not Found Ressource introuvable
409 Conflict Ressource déjà existante (doublon)
422 Unprocessable Entity Erreur de validation des données
429 Too Many Requests Limite de taux atteinte
500 Internal Server Error Erreur côté serveur

Endpoints par module

Auth (/auth)

POST /auth/token

Public. Connexion et obtention du JWT.

curl -s -X POST http://localhost:8000/auth/token \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"Admin1234!"}'

Réponse :

{
  "access_token": "eyJhbGci...",
  "token_type": "bearer"
}


GET /auth/me

Informations sur l'utilisateur actuellement connecté.

curl -H "Authorization: Bearer $TOKEN" http://localhost:8000/auth/me

Réponse :

{
  "username": "admin",
  "email": "[email protected]",
  "roles": ["admin"]
}


POST /auth/change-password

Changer son propre mot de passe.

curl -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  http://localhost:8000/auth/change-password \
  -d '{"current_password":"Admin1234!","new_password":"NewPass5678!"}'

GET /auth/roles

Public. Lister les rôles disponibles.

curl http://localhost:8000/auth/roles

GET /auth/users

Admin. Lister tous les utilisateurs.

curl -H "Authorization: Bearer $TOKEN" http://localhost:8000/auth/users

POST /auth/users

Admin. Créer un nouvel utilisateur.

curl -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  http://localhost:8000/auth/users \
  -d '{
    "username": "jdupont",
    "email": "[email protected]",
    "password": "SecurePass1!",
    "roles": ["uploader"]
  }'

PATCH /auth/users/{username}

Admin. Modifier un utilisateur existant.

curl -X PATCH -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  http://localhost:8000/auth/users/jdupont \
  -d '{"roles":["uploader","auditor"]}'

DELETE /auth/users/{username}

Admin. Supprimer un utilisateur.

curl -X DELETE -H "Authorization: Bearer $TOKEN" \
  http://localhost:8000/auth/users/jdupont

POST /auth/users/{username}/reset-password

Admin. Réinitialiser le mot de passe d'un utilisateur.

curl -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  http://localhost:8000/auth/users/jdupont/reset-password \
  -d '{"new_password":"TempPass9!"}'

POST /auth/forgot-password

Public, rate-limité. Demander un e-mail de réinitialisation.

curl -X POST http://localhost:8000/auth/forgot-password \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]"}'

POST /auth/reset-password

Public, rate-limité. Réinitialiser le mot de passe avec le token reçu par e-mail.

curl -X POST http://localhost:8000/auth/reset-password \
  -H "Content-Type: application/json" \
  -d '{"token":"<reset_token>","new_password":"NewPass5678!"}'

GET /auth/api-tokens

Admin. Lister les API tokens existants.

curl -H "Authorization: Bearer $TOKEN" http://localhost:8000/auth/api-tokens

POST /auth/api-tokens

Admin. Créer un API token.

curl -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  http://localhost:8000/auth/api-tokens \
  -d '{"name":"gitlab-ci","roles":["uploader"]}'

Réponse :

{
  "id": "tok_abc123",
  "token": "repod_xxxxxxxxxx",
  "name": "gitlab-ci",
  "roles": ["uploader"]
}

Le token brut repod_xxxxxxxxxx n'est affiché qu'une seule fois. Conservez-le immédiatement.


DELETE /auth/api-tokens/{token_id}

Admin. Révoquer un API token.

curl -X DELETE -H "Authorization: Bearer $TOKEN" \
  http://localhost:8000/auth/api-tokens/tok_abc123

Packages (/packages, /artifacts)

GET /packages/

Lister les packages avec recherche et filtres.

curl -H "Authorization: Bearer $TOKEN" \
  "http://localhost:8000/packages/?q=nginx&distribution=jammy"

GET /artifacts/

Lister tous les artefacts.

curl -H "Authorization: Bearer $TOKEN" http://localhost:8000/artifacts/

GET /artifacts/{name}

Informations sur un package.

curl -H "Authorization: Bearer $TOKEN" http://localhost:8000/artifacts/nginx

GET /artifacts/{name}/dependencies

Dépendances d'un package.

curl -H "Authorization: Bearer $TOKEN" \
  http://localhost:8000/artifacts/nginx/dependencies

GET /artifacts/{name}/install

Commande d'installation d'un package.

curl -H "Authorization: Bearer $TOKEN" \
  http://localhost:8000/artifacts/nginx/install

GET /artifacts/{name}/{version}

Informations sur une version spécifique.

curl -H "Authorization: Bearer $TOKEN" \
  http://localhost:8000/artifacts/nginx/1.24.0

GET /artifacts/audit/logs

Auditor+. Consulter les journaux d'audit.

curl -H "Authorization: Bearer $TOKEN" \
  http://localhost:8000/artifacts/audit/logs

POST /artifacts/admin/sync-index

Maintainer+. Synchroniser l'index des packages.

curl -X POST -H "Authorization: Bearer $TOKEN" \
  http://localhost:8000/artifacts/admin/sync-index

Upload (/upload)

POST /upload/

Uploader+, rate-limité (20/min). Publier un fichier .deb.

Champ formulaire Type Description
file fichier Fichier .deb à publier
distribution string Codename cible (ex. jammy)
curl -X POST -H "Authorization: Bearer $TOKEN" \
  -F "file=@mypackage_1.0.0_amd64.deb" \
  -F "distribution=jammy" \
  http://localhost:8000/upload/

Réponse (201) :

{
  "name": "mypackage",
  "version": "1.0.0",
  "arch": "amd64",
  "distribution": "jammy",
  "status": "indexed"
}


Import (/import)

GET /import/search

Rechercher un package dans l'index APT.

Paramètre Type Description
q string Terme de recherche
limit int Nombre max de résultats
source_id string Filtrer par source APT
curl -H "Authorization: Bearer $TOKEN" \
  "http://localhost:8000/import/search?q=nginx&limit=10"

GET /import/resolve/{package_name}

Résoudre les dépendances en ligne pour un package.

curl -H "Authorization: Bearer $TOKEN" \
  http://localhost:8000/import/resolve/nginx

POST /import/fetch

Uploader+, rate-limité (10/min). Importer un package depuis internet.

curl -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  http://localhost:8000/import/fetch \
  -d '{
    "name": "nginx",
    "version": "1.24.0",
    "arch": "amd64",
    "distribution": "jammy"
  }'

POST /import/batch

Uploader+, rate-limité (5/min). Import en lot.

curl -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  http://localhost:8000/import/batch \
  -d '{
    "packages": [
      {"name":"nginx","version":"1.24.0","arch":"amd64","distribution":"jammy"},
      {"name":"curl","version":"7.81.0","arch":"amd64","distribution":"jammy"}
    ]
  }'

GET /import/sync-status

Statut de synchronisation de toutes les sources APT.

curl -H "Authorization: Bearer $TOKEN" http://localhost:8000/import/sync-status

POST /import/sync

Maintainer+, rate-limité (3/min). Synchroniser toutes les sources APT.

curl -X POST -H "Authorization: Bearer $TOKEN" http://localhost:8000/import/sync

GET /import/groups

Lister les groupes d'import.

curl -H "Authorization: Bearer $TOKEN" http://localhost:8000/import/groups

DELETE /import/groups/{group_name}

Supprimer un groupe d'import.

curl -X DELETE -H "Authorization: Bearer $TOKEN" \
  http://localhost:8000/import/groups/mon-groupe

POST /import/sync/{source_id}

Maintainer+. Synchroniser une source APT spécifique.

curl -X POST -H "Authorization: Bearer $TOKEN" \
  http://localhost:8000/import/sync/ubuntu-jammy

POST /import/sync-security

Maintainer+. Synchroniser les sources de sécurité.

curl -X POST -H "Authorization: Bearer $TOKEN" \
  http://localhost:8000/import/sync-security

GET /import/sync-schedule

Prochaine synchronisation planifiée.

curl -H "Authorization: Bearer $TOKEN" http://localhost:8000/import/sync-schedule

Sécurité (/security)

GET /security/vulnerabilities

Lister les CVE sur l'ensemble des packages.

curl -H "Authorization: Bearer $TOKEN" \
  http://localhost:8000/security/vulnerabilities

GET /security/packages-posture

Résumé de la posture de sécurité.

curl -H "Authorization: Bearer $TOKEN" \
  http://localhost:8000/security/packages-posture

GET /security/packages/{name}/{version}/cve

CVE associées à une version de package.

curl -H "Authorization: Bearer $TOKEN" \
  http://localhost:8000/security/packages/nginx/1.24.0/cve

GET /security/review-queue

Auditor+. Packages en attente de revue RSSI.

curl -H "Authorization: Bearer $TOKEN" \
  http://localhost:8000/security/review-queue

POST /security/packages/{name}/{version}/decide

Maintainer+. Rendre une décision sur les CVE d'un package.

curl -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  http://localhost:8000/security/packages/nginx/1.24.0/decide \
  -d '{"decision":"accepted","comment":"Risque accepté après analyse."}'

POST /security/packages/{name}/{version}/rescan

Maintainer+. Déclencher un nouveau scan de vulnérabilités.

curl -X POST -H "Authorization: Bearer $TOKEN" \
  http://localhost:8000/security/packages/nginx/1.24.0/rescan

POST /security/packages/{name}/{version}/quarantine

Maintainer+. Mettre un package en quarantaine.

curl -X POST -H "Authorization: Bearer $TOKEN" \
  http://localhost:8000/security/packages/nginx/1.24.0/quarantine

GET /security/clamav/status

Statut du moteur antivirus ClamAV.

curl -H "Authorization: Bearer $TOKEN" http://localhost:8000/security/clamav/status

POST /security/clamav/update

Maintainer+. Mettre à jour la base de signatures ClamAV.

curl -X POST -H "Authorization: Bearer $TOKEN" \
  http://localhost:8000/security/clamav/update

SBOM (/sbom)

GET /sbom/export

Exporter le SBOM complet.

Paramètre Valeurs Description
format cyclonedx, spdx Format de sortie
distribution codename Filtrer par distribution
# CycloneDX
curl -H "Authorization: Bearer $TOKEN" \
  "http://localhost:8000/sbom/export?format=cyclonedx&distribution=jammy" \
  -o sbom.cdx.json

# SPDX
curl -H "Authorization: Bearer $TOKEN" \
  "http://localhost:8000/sbom/export?format=spdx&distribution=jammy" \
  -o sbom.spdx.json

GET /sbom/{name}/{version}

SBOM d'un package spécifique.

Paramètre Valeurs Description
format cyclonedx, spdx Format de sortie
arch ex. amd64 Architecture
curl -H "Authorization: Bearer $TOKEN" \
  "http://localhost:8000/sbom/nginx/1.24.0?format=cyclonedx&arch=amd64" \
  -o nginx-sbom.cdx.json

GET /sbom/preview

Aperçu du SBOM (limité).

curl -H "Authorization: Bearer $TOKEN" \
  "http://localhost:8000/sbom/preview?format=cyclonedx&distribution=jammy&limit=5"

Téléchargements (/downloads)

GET /downloads/stats

Statistiques de téléchargements.

Paramètre Valeurs Description
days 7, 30, 90 Période
curl -H "Authorization: Bearer $TOKEN" \
  "http://localhost:8000/downloads/stats?days=30"

Dashboard (/dashboard)

GET /dashboard/stats

Statistiques globales du dépôt.

curl -H "Authorization: Bearer $TOKEN" http://localhost:8000/dashboard/stats

GET /dashboard/history

Historique des événements.

curl -H "Authorization: Bearer $TOKEN" http://localhost:8000/dashboard/history

Distributions (/distributions)

GET /distributions/

Lister les distributions disponibles.

curl -H "Authorization: Bearer $TOKEN" http://localhost:8000/distributions/

GET /distributions/{codename}/packages

Packages présents dans une distribution.

curl -H "Authorization: Bearer $TOKEN" \
  http://localhost:8000/distributions/jammy/packages

POST /distributions/promote

Promouvoir un package vers une autre distribution.

curl -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  http://localhost:8000/distributions/promote \
  -d '{
    "name": "nginx",
    "version": "1.24.0",
    "arch": "amd64",
    "from_distribution": "jammy",
    "to_distribution": "focal"
  }'

POST /distributions/migrate

Migrer des packages entre distributions.

curl -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  http://localhost:8000/distributions/migrate \
  -d '{
    "from_distribution": "focal",
    "to_distribution": "jammy",
    "packages": ["nginx","curl"]
  }'

POST /distributions/init

Initialiser une nouvelle distribution.

curl -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  http://localhost:8000/distributions/init \
  -d '{"codename":"noble","description":"Ubuntu 24.04 LTS"}'

Paramètres (/settings)

Tous les endpoints /settings sont réservés aux admins.

GET /settings/

Lire la configuration complète (mots de passe masqués).

curl -H "Authorization: Bearer $TOKEN" http://localhost:8000/settings/

PATCH /settings/

Modifier la configuration.

curl -X PATCH -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  http://localhost:8000/settings/ \
  -d '{"retention_days": 90}'

POST /settings/test-webhook

Tester le webhook configuré.

curl -X POST -H "Authorization: Bearer $TOKEN" \
  http://localhost:8000/settings/test-webhook

GET /settings/gpg

Informations sur la clé GPG du dépôt.

curl -H "Authorization: Bearer $TOKEN" http://localhost:8000/settings/gpg

POST /settings/gpg/generate

Générer une nouvelle clé GPG.

curl -X POST -H "Authorization: Bearer $TOKEN" \
  http://localhost:8000/settings/gpg/generate

GET /settings/next-sync

Prochaine synchronisation planifiée.

curl -H "Authorization: Bearer $TOKEN" http://localhost:8000/settings/next-sync

POST /settings/test-ldap

Tester la connexion LDAP.

curl -X POST -H "Authorization: Bearer $TOKEN" \
  http://localhost:8000/settings/test-ldap

POST /settings/run-retention

Déclencher la politique de rétention manuellement.

curl -X POST -H "Authorization: Bearer $TOKEN" \
  http://localhost:8000/settings/run-retention

POST /settings/test-email

Envoyer un e-mail de test.

curl -X POST -H "Authorization: Bearer $TOKEN" \
  http://localhost:8000/settings/test-email

Santé (/health)

GET /health

Public. Bilan de santé complet avec statut de tous les sous-systèmes.

curl http://localhost:8000/health

Réponse :

{
  "status": "healthy",
  "subsystems": {
    "database": "ok",
    "storage": "ok",
    "clamav": "ok"
  }
}


GET /health/live

Public. Sonde de vivacité (renvoie toujours 200 si le service est démarré).

curl http://localhost:8000/health/live

GET /health/ready

Public. Sonde de disponibilité (indique si le service est prêt à accepter des requêtes).

curl http://localhost:8000/health/ready

Exemples complets

Créer un utilisateur et lui attribuer un rôle

# 1. Obtenir un token admin
TOKEN=$(curl -s -X POST http://localhost:8000/auth/token \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"Admin1234!"}' | jq -r .access_token)

# 2. Créer l'utilisateur
curl -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  http://localhost:8000/auth/users \
  -d '{
    "username": "deployer",
    "email": "[email protected]",
    "password": "Deploy9876!",
    "roles": ["uploader"]
  }'

# 3. Créer un API token pour les pipelines CI
curl -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  http://localhost:8000/auth/api-tokens \
  -d '{"name":"pipeline-deployer","roles":["uploader"]}' | jq -r .token

Publier et vérifier un package

# Upload
curl -X POST -H "Authorization: Bearer $TOKEN" \
  -F "file=@myapp_2.0.0_amd64.deb" \
  -F "distribution=jammy" \
  http://localhost:8000/upload/

# Vérifier la présence
curl -H "Authorization: Bearer $TOKEN" \
  http://localhost:8000/artifacts/myapp/2.0.0

# Vérifier les CVE
curl -H "Authorization: Bearer $TOKEN" \
  http://localhost:8000/security/packages/myapp/2.0.0/cve

Importer un package depuis les dépôts upstream

# Recherche
curl -H "Authorization: Bearer $TOKEN" \
  "http://localhost:8000/import/search?q=curl&limit=5" | jq

# Résoudre les dépendances
curl -H "Authorization: Bearer $TOKEN" \
  http://localhost:8000/import/resolve/curl | jq

# Import
curl -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  http://localhost:8000/import/fetch \
  -d '{"name":"curl","version":"7.81.0","arch":"amd64","distribution":"jammy"}'

Exporter le SBOM complet

# CycloneDX
curl -H "Authorization: Bearer $TOKEN" \
  "http://localhost:8000/sbom/export?format=cyclonedx&distribution=jammy" \
  -o sbom-jammy.cdx.json

# SPDX
curl -H "Authorization: Bearer $TOKEN" \
  "http://localhost:8000/sbom/export?format=spdx&distribution=jammy" \
  -o sbom-jammy.spdx.json

echo "SBOM exporté avec succès."

Intégration CI/CD

GitHub Actions — Publication d'un package

name: Publish package

on:
  push:
    tags:
      - 'v*'

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Build .deb
        run: make deb

      - name: Upload to repod
        env:
          REPOD_TOKEN: ${{ secrets.REPOD_TOKEN }}
          REPOD_URL: https://repo.example.com
        run: |
          curl -X POST "$REPOD_URL/upload/" \
            -H "Authorization: Bearer $REPOD_TOKEN" \
            -F "file=@mypackage_1.0.0_amd64.deb" \
            -F "distribution=jammy"

GitLab CI — Publication d'un package

stages:
  - build
  - deploy

build:
  stage: build
  script:
    - make deb

deploy:
  stage: deploy
  script:
    - |
      curl -X POST "$REPOD_URL/upload/" \
        -H "Authorization: Bearer $REPOD_TOKEN" \
        -F "file=@mypackage_1.0.0_amd64.deb" \
        -F "distribution=jammy"
  only:
    - tags

Ajoutez REPOD_TOKEN et REPOD_URL dans les variables CI/CD de votre projet GitLab.


Import automatisé depuis upstream

#!/usr/bin/env bash
set -euo pipefail

REPOD_URL="https://repo.example.com"
REPOD_TOKEN="${REPOD_TOKEN}"
DISTRIBUTION="jammy"

PACKAGES=("nginx" "curl" "openssl")

for pkg in "${PACKAGES[@]}"; do
  echo "Importation de $pkg..."
  curl -s -X POST -H "Authorization: Bearer $REPOD_TOKEN" \
    -H "Content-Type: application/json" \
    "$REPOD_URL/import/fetch" \
    -d "{\"name\":\"$pkg\",\"arch\":\"amd64\",\"distribution\":\"$DISTRIBUTION\"}"
done

Limites et rate limiting

Certains endpoints sont protégés par des limites de taux pour éviter les abus.

Endpoint Limite
POST /upload/ 20 requêtes / minute
POST /import/fetch 10 requêtes / minute
POST /import/batch 5 requêtes / minute
POST /import/sync 3 requêtes / minute
POST /auth/forgot-password Rate-limité (non divulgué)
POST /auth/reset-password Rate-limité (non divulgué)

En cas de dépassement, le serveur répond avec 429 Too Many Requests. Attendez la durée indiquée dans l'en-tête Retry-After avant de relancer la requête.

Niveaux de rôle

Les rôles sont cumulatifs (un rôle supérieur inclut les droits des rôles inférieurs) :

Rôle Droits
viewer Lecture seule
uploader Viewer + publication et import de packages
auditor Uploader + accès aux journaux et à la file de revue sécurité
maintainer Auditor + synchronisation, quarantaine, décisions CVE
admin Tous les droits, gestion des utilisateurs et de la configuration