Accès aux paquets
Par défaut, toute personne disposant de l’accès aux paquets dans votre organisation atteint chacun de ses paquets : un membre d’une équipe ayant l’écriture sur les paquets peut publier dans n’importe quel paquet de l’organisation, et le supprimer, quel que soit le dépôt auquel il appartient. L’accès par paquet restreint cela, à la manière de GitHub Packages et de GitLab.
Rien ne change tant qu’un propriétaire de l’organisation ne l’active pas, pour un paquet ou pour toute l’organisation.
Ce que fait l’accès par paquet
Pour un paquet en accès par paquet :
| Qui | Obtient |
|---|---|
| Propriétaires de l’organisation | Accès complet (lecture, publication, suppression). |
| Une personne ou un robot de registre | Le plus élevé entre : sa permission sur le dépôt lié du paquet (lecture, écriture ou administration), et la permission de chaque autorisation d’équipe sur le paquet pour une équipe dont il fait partie. |
| Un jeton de tâche Forgejo Actions | La publication si le paquet est lié au dépôt de la tâche elle-même ; sinon, ce que donne une autorisation Actions pour le dépôt de la tâche (lecture ou écriture). Une exécution de pull request provenant d’un fork ne fait jamais que lire. |
| Toute autre personne | Rien au-delà de ce que donne la visibilité de l’organisation (ci-dessous). |
- La lecture télécharge le paquet. L’écriture publie, ajoute un fichier et déplace un tag. L’administration permet en outre de supprimer des versions et de lier ou délier le dépôt. Un robot de registre ne supprime jamais, quelles que soient ses autorisations.
- La visibilité est inchangée. Dans une organisation publique, n’importe qui peut toujours lire chaque paquet, et dans une organisation limitée, n’importe quel utilisateur connecté le peut. L’accès par paquet limite alors qui peut publier et supprimer. Dans une organisation privée, il limite aussi la lecture.
- Il ne peut que restreindre. L’accès par paquet ne donne jamais à quiconque plus que ce que donnent les propres paramètres de paquets de l’organisation. Pour permettre à une équipe de publier un paquet, ses membres ont besoin de l’écriture sur les paquets dans l’organisation (l’équipe Members l’a), et l’accès par paquet les cantonne ensuite à ce paquet. La seule exception est l’autorisation Actions en écriture, qui permet aux tâches d’un autre dépôt de publier un paquet lié ailleurs.
- Dépôt lié. Un paquet est lié à un dépôt lorsqu’il est publié par une tâche Actions
de ce dépôt, d’après ses métadonnées (
repositoryde npm, le label de conteneurorg.opencontainers.image.source), ou dans les paramètres du paquet. Désactivez Hériter du dépôt lié pour vous appuyer uniquement sur les autorisations.
L’accès par paquet est disponible pour tous les types de paquets que sert le registre : Alpine, ALT, Arch, Cargo, Chef, Composer, Conan, Conda, conteneur, CRAN, Debian, générique, Go, Helm, Maven, npm, NuGet, Pub, PyPI, RPM, RubyGems, Swift et Vagrant.
L’activer
Dans la console : Sécurité › Accès › Accès aux paquets.
- Valeur par défaut de l’organisation : Toute l’organisation (par défaut) ou Par paquet, pour chaque paquet d’un type pris en charge qui n’a pas de réglage propre.
- Configurer un paquet : pour chaque paquet, Par paquet, Toute l’organisation ou Suivre l’organisation, et s’il hérite de son dépôt lié. Le paquet n’a pas besoin d’exister déjà : un réglage effectué avant la première publication s’applique à lui.
- Ajouter une autorisation sur un paquet configuré : une équipe (lecture, écriture ou administration) ou les tâches Actions d’un dépôt (lecture ou écriture).
Ou avec l’API, avec un jeton d’API doté du scope policy:write (policy:read
pour la lecture). Un / dans un nom de paquet est envoyé sous la forme %2F :
API=https://frem.sh/_app/api/v1/orgs/acme
curl -X PUT -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"mode":"granular","inherit_repo":true}' "$API/packages/container/team%2Fapp/access"
curl -X PUT -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"permission":"write"}' "$API/packages/container/team%2Fapp/access/teams/release-managers"
curl -X PUT -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"permission":"write"}' "$API/packages/container/team%2Fapp/access/actions/release-pipeline"Noms protégés
Une règle de protection désigne des paquets par type (ou tous les types pris en charge) et par motif de nom, et liste qui peut y publier et qui peut les supprimer : les propriétaires de l’organisation, les robots de registre, les membres d’équipes désignées et les tâches Actions de dépôts désignés. Toute autre personne est refusée, quel que soit le réglage d’accès du paquet. Lorsque plusieurs règles correspondent à un paquet, toutes doivent l’autoriser.
Dans le motif, * correspond à n’importe quels caractères, / compris, et ? à un seul caractère ; la casse
n’a pas d’importance. Par exemple, release/* avec May publish: registry robots, Actions jobs of
release-pipeline réserve les images de release à la CI.
curl -X POST -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"type":"container","name_pattern":"release/*","push":{"owners":false,"robots":true,"actions":["release-pipeline"]},"delete":{"owners":true}}' \
"$API/packages/protection-rules"Listes et index de paquets
Dans une organisation qui utilise l’accès par paquet, les listes et les index omettent les paquets que l’appelant ne peut pas lire, par nom et avec toutes leurs versions :
- la liste des paquets de l’API,
/api/v1/packages/<org>; - la recherche npm, l’
index.yamlde Helm, la recherche NuGet (query),search.jsonetlist.jsonde Composer, la recherche Cargo,searchetuniversede Chef,repodata.jsonde Conda,versionsde RubyGems,PACKAGESde CRAN, la recherche Conan et la rechercheidentifiersde Swift.
Le registre vérifie la liste au moment de la renvoyer, ce qui ajoute généralement moins d’un dixième de seconde à ces
requêtes. S’il ne peut pas vérifier une liste, il répond 503 avec Retry-After plutôt que de l’afficher
non filtrée. Les organisations qui n’utilisent pas l’accès par paquet obtiennent les listes du registre sans modification.
À quoi ressemble un refus
Une requête refusée répond 403 avec le motif (DENIED dans le format d’erreur du registre de
conteneurs), avant toute écriture. Chaque refus figure dans le
journal d’audit de l’organisation sous package_access.denied, et une
publication ou une suppression refusée également sous package.upload.refused ou package.delete.refused avec le motif
package_access:<reason>.
En tant que code
Le module de configuration en tant que code gère l’ensemble :
module "org" {
source = "./modules/fremforge-org"
org = "acme"
package_access_default = "legacy"
packages = {
"container/team/app" = {
mode = "granular"
teams = { release-managers = "admin" }
actions = { release-pipeline = "write" }
}
}
package_protection_rules = {
releases = { type = "container", name_pattern = "release/*", push = { owners = false, robots = true } }
}
}Limites
- Une modification d’un réglage, d’une autorisation, d’une règle ou des membres d’une équipe s’applique en moins d’une minute : le registre met brièvement ses décisions en cache.
- Ces listes ne sont pas filtrées : la liste des paquets dans l’interface web, les index de dépôt signés (les
Release/Packagesde Debian,repodatade RPM,APKINDEXd’Alpine, la base de données Arch et les fichiers de base ALT, dont une réécriture casserait la signature), les variantes compressées (PACKAGES.gz,repodata.json.bz2, la famillespecs.4.8.gzde RubyGems), les flux XML NuGet v2 et la liste des tags de conteneur. Elles montrent les noms et versions des paquets à toute personne pouvant lire les paquets de l’organisation, mais pas le contenu des paquets. - Un envoi qui ne nomme son paquet qu’à l’intérieur du fichier envoyé est contrôlé par rapport à ce nom.
Lorsque le registre ne peut pas lire le nom (un
.tar.bz2Conda, une archive de contrôle Debian compressée en xz ou un paquet Arch), l’envoi est refusé dans une organisation qui utilise l’accès par paquet pour ce type. Utilisez.conda, ou une compression gzip ou zstd. - Un yank RubyGems doit nommer la gem dans la chaîne de requête, par exemple
curl -X DELETE ".../rubygems/api/v1/gems/yank?gem_name=mygem&version=1.0.0". Un yank qui ne la nomme que dans un corps de formulaire est refusé dans une organisation qui utilise l’accès par paquet pour RubyGems.