Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
# CRDs are applied/validated on-cluster, not here.
run: kubectl kustomize deploy/ > /dev/null

- name: 🧪 Test default-off Admins policy
- name: 🧪 Test active Admins policy
run: bash tests/admin-team-policy.sh

ci-required-checks:
Expand Down
3 changes: 1 addition & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,9 @@ for the architecture, the GitHub App credential setup, and the Observe-first ado
| Path | Contents |
|---|---|
| `deploy/repositories/<repo>.yaml` | one `Repository` per managed repo (settings, merge/signoff, metadata) |
| `deploy/teams/` | one `Team` per file; default-off teams remain unlisted until activation |
| `deploy/teams/` | one `Team` per file; includes the active Maintainers and Admins teams |
| `deploy/team-memberships/` | one explicit user-to-team membership per file |
| `deploy/team-repositories/` | one team-to-repository permission grant per file |
| `tests/fixtures/` | validation-only enabled renders for default-off policy slices |
| `deploy/labels/<repo>.yaml` | one `IssueLabels` per repo; canonical taxonomy in `labels/kustomization.yaml` |
| `deploy/provider-config.yaml` | the provider-upjet-github `ProviderConfig` (App credentials) |
| `deploy/external-secret.yaml` | the `ExternalSecret` sourcing the GitHub App credentials |
Expand Down
32 changes: 14 additions & 18 deletions deploy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,11 @@ out-of-band changes made in the GitHub UI.
then a single `archived: true` flip; the two-phase lifecycle is documented in
that dir's `kustomization.yaml`.
- `teams/` — one `Team` per file. `maintainers` is Observe-adopted; the
separate `admins` policy remains default-off until its resources are listed.
separate `admins` policy actively manages explicit repository-admin grants.
- `team-memberships/` — one `TeamMembership` per file (`add-<user>-to-<team>.yaml`).
- `team-repositories/` — one `TeamRepository` per file (`grant-<team>-on-<repo>.yaml`),
each granting a team a permission on a repo. A file is inert until its
directory Kustomization lists it; the Admins policy uses this as its
default-off activation boundary.
each granting a team a permission on a repo. The active policy grants
`maintain` to Maintainers and `admin` to Admins without claiming Delete.
- `labels/` — one `IssueLabels` per managed repo. The canonical org label
taxonomy lives once in `labels/kustomization.yaml` (a shared patch appended to
every repo); each `<repo>.yaml` adds only that repo's Dependabot/Renovate
Expand Down Expand Up @@ -102,24 +101,21 @@ for the architecture, the GitHub App credential setup, and the **Observe-first**
adoption flow for bringing an existing repository under management without any
risk of recreating or deleting it.

## Default-off Admins policy
## Admins policy

Issue [#95](https://github.com/devantler-tech/.github/issues/95) defines the
separate `Admins` team, its explicit maintainer membership, and `admin`
grants for the 19 active portfolio repositories. The archived
`reusable-workflows` repository and not-yet-active `kyverno-policies`
repository are excluded.
Issue [#95](https://github.com/devantler-tech/.github/issues/95) and PR
[#96](https://github.com/devantler-tech/.github/pull/96) defined and validated
the separate `Admins` team, its explicit maintainer membership, and its
repository grants in both disabled and enabled states. Issue
[#102](https://github.com/devantler-tech/.github/issues/102) activates that
policy for the 20 active portfolio repositories, including `kyverno-policies`.
The archived `reusable-workflows` repository remains excluded.

The policy files deliberately remain absent from the production
`teams/`, `team-memberships/`, and `team-repositories/` resource lists.
Validate both states with:
The active policy is fully declarative and omits both `Delete` management and
external names, so it cannot delete teams, memberships, or grants. Validate the
production render and policy invariants with:

```sh
kubectl kustomize deploy/ > /dev/null
kubectl kustomize tests/fixtures/admin-team-enabled \
--load-restrictor LoadRestrictionsNone > /dev/null
bash tests/admin-team-policy.sh
```

Activation is a separate issue-backed change that lists the reviewed policy
files in those three production Kustomizations.
3 changes: 1 addition & 2 deletions deploy/team-memberships/add-devantler-to-admins.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# Default-off Admins-team membership. Activation lists this file alongside the
# team and grants in their three production Kustomizations.
# Active Admins-team membership, managed without claiming Delete.
apiVersion: team.github.m.upbound.io/v1alpha1
kind: TeamMembership
metadata:
Expand Down
1 change: 1 addition & 0 deletions deploy/team-memberships/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- add-devantler-to-maintainers.yaml
- add-devantler-to-admins.yaml
5 changes: 2 additions & 3 deletions deploy/team-repositories/grant-admins-on-actions.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Default-off Admins-team repository grant. No external-name is set because the
# separate team and its admin grant do not exist yet; activation creates them
# without claiming Delete management.
# Admins-team repository grant. No external-name is set because the separate
# team and its admin grant are created declaratively without claiming Delete.
apiVersion: team.github.m.upbound.io/v1alpha1
kind: TeamRepository
metadata:
Expand Down
5 changes: 2 additions & 3 deletions deploy/team-repositories/grant-admins-on-agent-plugins.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Default-off Admins-team repository grant. No external-name is set because the
# separate team and its admin grant do not exist yet; activation creates them
# without claiming Delete management.
# Admins-team repository grant. No external-name is set because the separate
# team and its admin grant are created declaratively without claiming Delete.
apiVersion: team.github.m.upbound.io/v1alpha1
kind: TeamRepository
metadata:
Expand Down
5 changes: 2 additions & 3 deletions deploy/team-repositories/grant-admins-on-agent-skills.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Default-off Admins-team repository grant. No external-name is set because the
# separate team and its admin grant do not exist yet; activation creates them
# without claiming Delete management.
# Admins-team repository grant. No external-name is set because the separate
# team and its admin grant are created declaratively without claiming Delete.
apiVersion: team.github.m.upbound.io/v1alpha1
kind: TeamRepository
metadata:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Default-off Admins-team repository grant. No external-name is set because the
# separate team and its admin grant do not exist yet; activation creates them
# without claiming Delete management.
# Admins-team repository grant. No external-name is set because the separate
# team and its admin grant are created declaratively without claiming Delete.
apiVersion: team.github.m.upbound.io/v1alpha1
kind: TeamRepository
metadata:
Expand Down
5 changes: 2 additions & 3 deletions deploy/team-repositories/grant-admins-on-aws.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Default-off Admins-team repository grant. No external-name is set because the
# separate team and its admin grant do not exist yet; activation creates them
# without claiming Delete management.
# Admins-team repository grant. No external-name is set because the separate
# team and its admin grant are created declaratively without claiming Delete.
apiVersion: team.github.m.upbound.io/v1alpha1
kind: TeamRepository
metadata:
Expand Down
5 changes: 2 additions & 3 deletions deploy/team-repositories/grant-admins-on-dot-github.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Default-off Admins-team repository grant. No external-name is set because the
# separate team and its admin grant do not exist yet; activation creates them
# without claiming Delete management.
# Admins-team repository grant. No external-name is set because the separate
# team and its admin grant are created declaratively without claiming Delete.
apiVersion: team.github.m.upbound.io/v1alpha1
kind: TeamRepository
metadata:
Expand Down
5 changes: 2 additions & 3 deletions deploy/team-repositories/grant-admins-on-dotnet-template.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Default-off Admins-team repository grant. No external-name is set because the
# separate team and its admin grant do not exist yet; activation creates them
# without claiming Delete management.
# Admins-team repository grant. No external-name is set because the separate
# team and its admin grant are created declaratively without claiming Delete.
apiVersion: team.github.m.upbound.io/v1alpha1
kind: TeamRepository
metadata:
Expand Down
5 changes: 2 additions & 3 deletions deploy/team-repositories/grant-admins-on-fleet-gitops.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Default-off Admins-team repository grant. No external-name is set because the
# separate team and its admin grant do not exist yet; activation creates them
# without claiming Delete management.
# Admins-team repository grant. No external-name is set because the separate
# team and its admin grant are created declaratively without claiming Delete.
apiVersion: team.github.m.upbound.io/v1alpha1
kind: TeamRepository
metadata:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Default-off Admins-team repository grant. No external-name is set because the
# separate team and its admin grant do not exist yet; activation creates them
# without claiming Delete management.
# Admins-team repository grant. No external-name is set because the separate
# team and its admin grant are created declaratively without claiming Delete.
apiVersion: team.github.m.upbound.io/v1alpha1
kind: TeamRepository
metadata:
Expand Down
5 changes: 2 additions & 3 deletions deploy/team-repositories/grant-admins-on-go-template.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Default-off Admins-team repository grant. No external-name is set because the
# separate team and its admin grant do not exist yet; activation creates them
# without claiming Delete management.
# Admins-team repository grant. No external-name is set because the separate
# team and its admin grant are created declaratively without claiming Delete.
apiVersion: team.github.m.upbound.io/v1alpha1
kind: TeamRepository
metadata:
Expand Down
5 changes: 2 additions & 3 deletions deploy/team-repositories/grant-admins-on-homebrew-tap.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Default-off Admins-team repository grant. No external-name is set because the
# separate team and its admin grant do not exist yet; activation creates them
# without claiming Delete management.
# Admins-team repository grant. No external-name is set because the separate
# team and its admin grant are created declaratively without claiming Delete.
apiVersion: team.github.m.upbound.io/v1alpha1
kind: TeamRepository
metadata:
Expand Down
5 changes: 2 additions & 3 deletions deploy/team-repositories/grant-admins-on-ksail.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Default-off Admins-team repository grant. No external-name is set because the
# separate team and its admin grant do not exist yet; activation creates them
# without claiming Delete management.
# Admins-team repository grant. No external-name is set because the separate
# team and its admin grant are created declaratively without claiming Delete.
apiVersion: team.github.m.upbound.io/v1alpha1
kind: TeamRepository
metadata:
Expand Down
16 changes: 16 additions & 0 deletions deploy/team-repositories/grant-admins-on-kyverno-policies.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Admins-team repository grant. No external-name is set because the separate
# team and its admin grant are created declaratively without claiming Delete.
apiVersion: team.github.m.upbound.io/v1alpha1
kind: TeamRepository
metadata:
name: admins-kyverno-policies
spec:
managementPolicies: ["Observe", "Create", "Update", "LateInitialize"]
forProvider:
teamIdRef:
name: admins
repository: kyverno-policies
permission: admin
providerConfigRef:
kind: ProviderConfig
name: default
5 changes: 2 additions & 3 deletions deploy/team-repositories/grant-admins-on-maintenance.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Default-off Admins-team repository grant. No external-name is set because the
# separate team and its admin grant do not exist yet; activation creates them
# without claiming Delete management.
# Admins-team repository grant. No external-name is set because the separate
# team and its admin grant are created declaratively without claiming Delete.
apiVersion: team.github.m.upbound.io/v1alpha1
kind: TeamRepository
metadata:
Expand Down
5 changes: 2 additions & 3 deletions deploy/team-repositories/grant-admins-on-monorepo.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Default-off Admins-team repository grant. No external-name is set because the
# separate team and its admin grant do not exist yet; activation creates them
# without claiming Delete management.
# Admins-team repository grant. No external-name is set because the separate
# team and its admin grant are created declaratively without claiming Delete.
apiVersion: team.github.m.upbound.io/v1alpha1
kind: TeamRepository
metadata:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Default-off Admins-team repository grant. No external-name is set because the
# separate team and its admin grant do not exist yet; activation creates them
# without claiming Delete management.
# Admins-team repository grant. No external-name is set because the separate
# team and its admin grant are created declaratively without claiming Delete.
apiVersion: team.github.m.upbound.io/v1alpha1
kind: TeamRepository
metadata:
Expand Down
5 changes: 2 additions & 3 deletions deploy/team-repositories/grant-admins-on-platform.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Default-off Admins-team repository grant. No external-name is set because the
# separate team and its admin grant do not exist yet; activation creates them
# without claiming Delete management.
# Admins-team repository grant. No external-name is set because the separate
# team and its admin grant are created declaratively without claiming Delete.
apiVersion: team.github.m.upbound.io/v1alpha1
kind: TeamRepository
metadata:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Default-off Admins-team repository grant. No external-name is set because the
# separate team and its admin grant do not exist yet; activation creates them
# without claiming Delete management.
# Admins-team repository grant. No external-name is set because the separate
# team and its admin grant are created declaratively without claiming Delete.
apiVersion: team.github.m.upbound.io/v1alpha1
kind: TeamRepository
metadata:
Expand Down
5 changes: 2 additions & 3 deletions deploy/team-repositories/grant-admins-on-unifi.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Default-off Admins-team repository grant. No external-name is set because the
# separate team and its admin grant do not exist yet; activation creates them
# without claiming Delete management.
# Admins-team repository grant. No external-name is set because the separate
# team and its admin grant are created declaratively without claiming Delete.
apiVersion: team.github.m.upbound.io/v1alpha1
kind: TeamRepository
metadata:
Expand Down
5 changes: 2 additions & 3 deletions deploy/team-repositories/grant-admins-on-wedding-app.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Default-off Admins-team repository grant. No external-name is set because the
# separate team and its admin grant do not exist yet; activation creates them
# without claiming Delete management.
# Admins-team repository grant. No external-name is set because the separate
# team and its admin grant are created declaratively without claiming Delete.
apiVersion: team.github.m.upbound.io/v1alpha1
kind: TeamRepository
metadata:
Expand Down
29 changes: 25 additions & 4 deletions deploy/team-repositories/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# `TeamRepository` resources — one per file, named `grant-<team>-on-<repo>.yaml`, each
# granting a team a permission on a repository. Existing access is adopted Observe-first;
# access the team did not yet hold is Created at `maintain`. Grant a new repo by dropping
# a `grant-maintainers-on-<repo>.yaml` here and listing it below. See ../README.md and
# the platform repo's docs/github-management.md.
# granting a team a permission on a repository. Existing Maintainers access is adopted
# Observe-first; new Maintainers access is Created at `maintain`. Admins grants are
# Created at `admin` without claiming Delete. See ../README.md and the platform repo's
# docs/github-management.md.
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
Expand All @@ -21,3 +21,24 @@ resources:
- grant-maintainers-on-provider-upjet-unifi.yaml
- grant-maintainers-on-aws.yaml
- grant-maintainers-on-kyverno-policies.yaml
# Active Admins policy (one admin grant per active repository).
- grant-admins-on-dot-github.yaml
- grant-admins-on-actions.yaml
- grant-admins-on-agent-plugins.yaml
- grant-admins-on-agent-skills.yaml
- grant-admins-on-ascoachingogvaner.yaml
- grant-admins-on-aws.yaml
- grant-admins-on-dotnet-template.yaml
- grant-admins-on-fleet-gitops.yaml
- grant-admins-on-gitops-tenant-template.yaml
- grant-admins-on-go-template.yaml
- grant-admins-on-homebrew-tap.yaml
- grant-admins-on-ksail.yaml
- grant-admins-on-kyverno-policies.yaml
- grant-admins-on-maintenance.yaml
- grant-admins-on-monorepo.yaml
- grant-admins-on-platform.yaml
- grant-admins-on-platform-template.yaml
- grant-admins-on-provider-upjet-unifi.yaml
- grant-admins-on-unifi.yaml
- grant-admins-on-wedding-app.yaml
6 changes: 2 additions & 4 deletions deploy/teams/admins.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# Default-off feature policy: the separate administrative team chosen for
# repository-admin grants. This file is intentionally omitted from
# deploy/teams/kustomization.yaml. Activation lists the team, membership, and
# grants in their three production Kustomizations.
# Active administrative team for explicit repository-admin grants. The policy
# creates and updates the team without claiming Delete.
apiVersion: team.github.m.upbound.io/v1alpha1
kind: Team
metadata:
Expand Down
9 changes: 5 additions & 4 deletions deploy/teams/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# The `maintainers` team — the canonical CODEOWNERS owner across the devantler-tech
# suite (the "teams over individuals" convention), Observe-adopted by numeric id. One
# `Team` per file. Its membership lives in ../team-memberships/ and its team → repository
# access in ../team-repositories/. See ../README.md and the platform repo's
# The portfolio's declarative teams: `maintainers` is the canonical CODEOWNERS owner,
# Observe-adopted by numeric id; `admins` owns explicit repository-admin grants. One
# `Team` per file. Memberships live in ../team-memberships/ and repository access in
# ../team-repositories/. See ../README.md and the platform repo's
# docs/github-management.md for the Observe-first adoption flow.
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- maintainers.yaml
- admins.yaml
Loading