Skip to content

server: return 403 on unregistered onboarding cert/serial#155

Merged
milan-zededa merged 1 commit into
lf-edge:masterfrom
eriknordmark:register-403-per-spec
May 15, 2026
Merged

server: return 403 on unregistered onboarding cert/serial#155
milan-zededa merged 1 commit into
lf-edge:masterfrom
eriknordmark:register-403-per-spec

Conversation

@eriknordmark
Copy link
Copy Markdown
Contributor

Summary

The /register handler currently returns 401 Unauthorized when the
auth-container signature has already verified but the
(onboarding-cert, serial) combination is not in the controller's
pre-registration set. APIv2.md prescribes 403 Forbidden for that
case: "Valid credentials without authorization" (/register table)
and lines 159-160 state the response "MUST" be 403 when the
controller requires pre-registration and a device tries to register
without one.

401 remains in apiHandlerv2.register for the upstream cryptographic
failures: missing SenderCertHash, malformed sender cert, signature
mismatch. The change here is confined to the post-auth authorization
decision in registerProcess.

EVE's pkg/pillar/cmd/client/client.go already maps 403 to
LedBlinkOnboardingFailureNotFound and carries an XXX comment
flagging that the controller side of the spec is not yet honoured;
this PR removes that gap. Older EVE that does not special-case 403
falls back to the generic "Registration failed" log path, same as
it does today for 401 — no regression.

Test plan

  • New unit test TestRegisterProcessForbiddenForUnknownCert in
    pkg/server/commonHandler_test.go calls registerProcess
    against an empty memory.DeviceManager and asserts a 403 status.
  • go test ./pkg/server/ ./pkg/driver/... -count=1 passes
    (pkg/server, pkg/driver/file, pkg/driver/memory,
    pkg/driver/redis).
  • Eden e2e: paired test server_returns_403 in lf-edge/eden
    (tests/onboarding/) verifies EVE raises
    LedBlinkOnboardingFailureNotFound when adam returns 403 for
    an unregistered onboarding cert. To be added once this PR lands.

The /register handler currently returns 401 Unauthorized when the
auth-container signature has already verified upstream but the
(onboarding cert, serial) combination is not in the controller's
pre-registration set. APIv2.md prescribes 403 Forbidden for exactly
this case: "Valid credentials without authorization" (line 137 of
the /register section), and lines 159-160 repeat that the response
"MUST" be 403 when the controller requires pre-registration and a
device tries to register without one.

401 stays for the genuine authentication failures handled upstream in
apiHandlerv2.register (missing SenderCertHash, malformed sender cert,
signature mismatch). The change here is confined to the post-auth
authorization decision in registerProcess.

EVE's cmd/client already maps 403 to LedBlinkOnboardingFailureNotFound
(pkg/pillar/cmd/client/client.go) and carries an XXX comment flagging
that the controller side of the spec is not yet honoured; this commit
removes that gap. Older EVE that doesn't special-case 403 falls back
to the generic "Registration failed" log path, same as it does today
for 401 — no regression.

A handler test exercising the failure path against an empty
memory.DeviceManager confirms the new status code.

Signed-off-by: eriknordmark <erik@zededa.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@eriknordmark eriknordmark requested review from deitch, europaul and rene May 15, 2026 09:19
@eriknordmark eriknordmark marked this pull request as ready for review May 15, 2026 09:20
@milan-zededa milan-zededa merged commit b27f2aa into lf-edge:master May 15, 2026
2 checks passed
eriknordmark added a commit to eriknordmark/eden that referenced this pull request May 15, 2026
Picks up lf-edge/adam#155, which brings the /register handler in line
with the eve-api spec (APIv2.md §/register, lines 134-160): cert/serial
combinations that verify cryptographically but are not in the
controller's pre-registration set now return 403 Forbidden rather than
401 Unauthorized. EVE's pkg/pillar/cmd/client already maps 403 to
LedBlinkOnboardingFailureNotFound, so the longstanding eve-api gap on
the controller side is now closed.

Pinning a specific release rather than the rolling `snapshot` tag keeps
the version requirement expressible — if a future eden change needs
adam ≥ x.y.z, bumping the constant is the natural way to make that
explicit, and stale cached `snapshot` images on contributor machines
cannot silently regress. Override at config time remains supported via
`eden config set default --key=adam.tag --value=<sha-or-tag>`.

Signed-off-by: eriknordmark <erik@zededa.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
eriknordmark added a commit to eriknordmark/eden that referenced this pull request May 15, 2026
Covers the dark `case http.StatusForbidden` branch in selfRegister
(pkg/pillar/cmd/client/client.go:671-672) that raises
LedBlinkOnboardingFailureNotFound when the controller rejects an
onboarding cert that the device cryptographically possesses but that
is not present in the controller's pre-registration set. The branch
was effectively unreachable until lf-edge/adam#155 brought adam in
line with the eve-api spec (APIv2.md §/register: "Valid credentials
without authorization: 403").

The scenario captures every onboard-cert + device record that matches
this device's serial, DELETEs them via adam's /admin/onboard and
/admin/device admin endpoints, wipes /persist/status/uuid and
/persist/checkpoint/controllercerts on EVE, in-VM reboots, asserts
LedBlinkCounter=18 (OnboardingFailureNotFound), POSTs the saved
onboard cert back, reboots again, and verifies the device reaches
LedBlinkCounter=4 (Onboarded) with a fresh UUID on disk.

A short retry_ssh wrapper rides out the ~minute of ssh banner-exchange
flakiness right after each reboot, mirroring the pattern in the
existing server_changes_at_runtime and pre_provisioned_uuid scenarios.
The admin curl uses 127.0.0.1:adam.port (host-side docker port
mapping) because adam.ip in the eden config is the EVE-side IP, not
the host side.

Signed-off-by: eriknordmark <erik@zededa.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@eriknordmark eriknordmark deleted the register-403-per-spec branch May 15, 2026 20:16
eriknordmark added a commit to lf-edge/eden that referenced this pull request May 20, 2026
Picks up lf-edge/adam#155, which brings the /register handler in line
with the eve-api spec (APIv2.md §/register, lines 134-160): cert/serial
combinations that verify cryptographically but are not in the
controller's pre-registration set now return 403 Forbidden rather than
401 Unauthorized. EVE's pkg/pillar/cmd/client already maps 403 to
LedBlinkOnboardingFailureNotFound, so the longstanding eve-api gap on
the controller side is now closed.

Pinning a specific release rather than the rolling `snapshot` tag keeps
the version requirement expressible — if a future eden change needs
adam ≥ x.y.z, bumping the constant is the natural way to make that
explicit, and stale cached `snapshot` images on contributor machines
cannot silently regress. Override at config time remains supported via
`eden config set default --key=adam.tag --value=<sha-or-tag>`.

Signed-off-by: eriknordmark <erik@zededa.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.

2 participants