Skip to content

debian: default fresh installs to native certificate enrollment - #1451

Open
denisonbarbosa wants to merge 2 commits into
split/certificate-managementfrom
split/packaging-and-e2e
Open

debian: default fresh installs to native certificate enrollment#1451
denisonbarbosa wants to merge 2 commits into
split/certificate-managementfrom
split/packaging-and-e2e

Conversation

@denisonbarbosa

@denisonbarbosa denisonbarbosa commented Aug 10, 2026

Copy link
Copy Markdown
Member

Final part of the LDAP certificate enrollment work: flip fresh installs to the native backend and make the e2e suite prove which backend it actually tested.

This is part 4 of 4, split out of #1401.
#1448#1449 (engine)#1450 (API/CLI)this PR.
Targets split/certificate-management; will be retargeted to main as its parents land.

What this contains

Packaging

  • /etc/adsys.yaml is written with certificate_enrollment: ldap on first install only, and removed on purge. Upgrades and reinstalls keep whatever is already there, so no existing machine changes how it enrolls.
  • python3-cepces moves from Recommends to Suggests — adsys is in main and python3-cepces is still in universe, so recommending it would pull a universe package into a main package's default install set.
  • ca-certificates added to Depends (the native path installs discovered CA chains).
  • Go build dependency raised to the version go.mod already declares.
  • New packaging smoke autopkgtest covering install / upgrade / remove / purge.

e2e

  • The certificate assertion previously called getcert, so it only ever proved the CEPCES path. It now pins the backend and asserts what that backend should produce: for the native method the health, key match, chain and trust-store presence, plus renewal; for CEPCES the existing certmonger tracking; and the migration between the two.
  • The Jammy/Noble backport patches stopped applying after the Go bump, which only surfaced inside a Docker build. Regenerated, plus a test that replays build-deb.sh's patch invocation so packaging drift fails fast and locally.

Note for reviewers

/etc/adsys.yaml is created by postinst rather than shipped as a conffile. That is deliberate: it is a first-install default, not a package-owned configuration, so dpkg must not prompt about it or restore it after an administrator removes it. The reasoning is recorded inline in the maintainer script.

⚠️ The live Azure e2e run against real AD CS has not been executed — the test code is here, but it needs infrastructure. Worth gating merge of this part on a real run.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Defaults fresh installations to native LDAP certificate enrollment while preserving existing configurations.

Changes:

  • Updates Debian dependencies and configuration lifecycle scripts.
  • Expands E2E coverage for LDAP, CEPCES, renewal, and migration.
  • Refreshes Go 1.25 backport tooling and patch validation.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
debian/control Updates Go and runtime dependencies.
debian/adsys.postinst Creates the fresh-install LDAP default.
debian/adsys.postrm Removes configuration on purge.
debian/tests/control Registers packaging smoke coverage.
debian/tests/packaging-smoke Tests package lifecycle guarantees.
debian/adsys.apport Conditionally reports CEPCES details.
debian/copyright Adds vendored dependency notices.
e2e/scripts/Dockerfile.build Sources Go 1.25 for older releases.
e2e/scripts/patches/jammy.patch Refreshes Jammy build overrides.
e2e/scripts/patches_test.go Validates release patches locally.
e2e/cmd/run_tests/01_provision_client/main.go Stops installing CEPCES by default.
e2e/cmd/run_tests/11_test_pro_managers/main.go Exercises certificate backends and migration.
Suppressed comments (2)

e2e/cmd/run_tests/11_test_pro_managers/main.go:220

  • The daemon is still using the LDAP manager created at startup after this file edit; adsys-gpo-refresh only asks that existing daemon to update policy. Restart adsysd first, otherwise no CEPCES enrollment is started and the following getcert poll times out.
		if _, err := rootClient.Run(ctx, "systemctl restart adsys-gpo-refresh"); err != nil {

e2e/cmd/run_tests/11_test_pro_managers/main.go:232

  • This switch back has the same lifetime issue: changing YAML does not rebuild the running certificate manager, and restarting the refresh unit only calls the current CEPCES-configured daemon. Restart adsysd before refreshing so the migration is exercised with a newly configured LDAP manager.
		if _, err := rootClient.Run(ctx, "systemctl restart adsys-gpo-refresh"); err != nil {

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread e2e/cmd/run_tests/11_test_pro_managers/main.go Outdated
Comment thread e2e/cmd/run_tests/11_test_pro_managers/main.go Outdated
Comment thread e2e/cmd/run_tests/11_test_pro_managers/main.go Outdated

@adombeck adombeck left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll wait until the Copilot comments were addressed before reviewing this. Please request a review again when that's done. Thanks!

@denisonbarbosa
denisonbarbosa force-pushed the split/packaging-and-e2e branch from 1eb37fc to 2c838be Compare August 11, 2026 11:28
@denisonbarbosa

Copy link
Copy Markdown
Member Author

All Copilot comments are addressed in e2e: switch the enrollment backend the way a machine really does:

  • the backend switch now restarts adsysd before triggering the refresh, since adsys-gpo-refresh only asks the already-running daemon to update policy and the certificate manager is built once at startup;
  • /etc/adsys.yaml is created before sed edits it, so pinning the backend works on an image without a configuration file;
  • the migration assertion requires the certmonger request to be gone entirely rather than just out of MONITORING.

It also restores the documentation about new installations defaulting to the native backend, which moved here from #1449 because this is the change that makes it true.

@adombeck ready for your review.

Comment thread debian/control
Comment thread debian/copyright Outdated
@denisonbarbosa
denisonbarbosa force-pushed the split/packaging-and-e2e branch from 2c838be to 1e4fd9e Compare August 11, 2026 11:50
Comment thread e2e/cmd/run_tests/11_test_pro_managers/main.go
@denisonbarbosa
denisonbarbosa force-pushed the split/packaging-and-e2e branch 3 times, most recently from b5730d9 to 22bdc48 Compare August 12, 2026 11:51
Comment thread debian/copyright Outdated
@denisonbarbosa
denisonbarbosa force-pushed the split/packaging-and-e2e branch from 22bdc48 to f817091 Compare August 12, 2026 13:18
@denisonbarbosa
denisonbarbosa force-pushed the split/packaging-and-e2e branch from f817091 to 7112e13 Compare August 12, 2026 13:32
@denisonbarbosa
denisonbarbosa force-pushed the split/packaging-and-e2e branch from 7112e13 to fd46ca7 Compare August 12, 2026 15:23
@denisonbarbosa
denisonbarbosa force-pushed the split/packaging-and-e2e branch from fd46ca7 to 21b78de Compare August 12, 2026 15:36
Comment thread conf.example/adsys.yaml Outdated
Comment thread conf.example/adsys.yaml
@denisonbarbosa
denisonbarbosa force-pushed the split/packaging-and-e2e branch 2 times, most recently from 09452f2 to eeb6685 Compare August 13, 2026 12:52
denisonbarbosa and others added 2 commits August 17, 2026 07:42
The native backend is the one we want new deployments on, but the code
default has to stay cepces so that upgrading a machine never silently
changes how it enrolls. Packaging is the only place that can tell the
two apart.

Write /etc/adsys.yaml with the ldap method on first install only, when
no configuration exists yet, and remove it again on purge. Upgrades and
reinstalls keep whatever is already there. The file is created by the
maintainer script rather than shipped as a conffile because it is a
first-install default, not a package-owned configuration: dpkg must not
prompt about it or restore it once an administrator has removed it.

python3-cepces moves from Recommends to Suggests: adsys is in main and
python3-cepces is still in universe, so recommending it would pull a
universe package into a main package's default install set. Depend on
ca-certificates instead, which the native path now needs to install
discovered CA chains, and raise the Go build dependency to the version
the module already declares.

The configuration sample and the certificate guides record the split
this creates, since packaging is what makes it true: new installations
come up on the native backend, existing ones keep cepces until an
administrator opts in.

A packaging smoke autopkgtest covers the install, upgrade, remove and
purge paths for the new configuration file.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The certificate assertion called getcert, so it only ever proved the
CEPCES path worked. On an image installed fresh - which now selects the
native backend - it would fail, and on an upgraded image it would keep
testing the legacy path while claiming to cover enrollment.

Pin the backend explicitly and assert what that backend is supposed to
produce: for the native method the certificate health, the key match,
the chain and its presence in the system trust store, plus renewal;
for CEPCES the existing certmonger tracking; and the migration between
the two.

Pinning a backend restarts adsysd rather than only adsys-gpo-refresh.
That unit runs adsysctl update --all against the daemon that is already
running, and the daemon builds its certificate manager once at startup:
its configuration reload covers verbosity, socket and timeout only.
Refreshing alone would exercise every switch against the previously
configured manager, so the test could pass without ever running the
path it claims to cover. The selection also creates /etc/adsys.yaml
when it is absent, because a base or upgraded image need not ship one
and sed fails on a missing file.

Migrating back to the native method requires the certmonger request to
be gone rather than merely out of MONITORING: a request left in an
error or transitional state still means certmonger owns the same files.

The Jammy and Noble backport patches no longer applied to debian/control
after the Go toolchain bump, which only surfaced inside a Docker build.
Regenerate them and add a test that replays the patch invocation from
build-deb.sh, so packaging drift fails fast and locally.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@denisonbarbosa
denisonbarbosa force-pushed the split/packaging-and-e2e branch from eeb6685 to 648f651 Compare August 17, 2026 11:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants