Skip to content

Authorize console-triggered pipeline commands during bootstrap - #630

Merged
kayjoosten merged 2 commits into
mainfrom
feature/issue-629-bootstrap-yubikey-authorization
Jul 30, 2026
Merged

Authorize console-triggered pipeline commands during bootstrap#630
kayjoosten merged 2 commits into
mainfrom
feature/issue-629-bootstrap-yubikey-authorization

Conversation

@kayjoosten

Copy link
Copy Markdown
Contributor

Why is this change needed?
Prior to this change, console bootstrap commands (identity, yubikey, sms, gssp, migrate) ran without a security token. Creating an identity for a not-yet-configured institution triggers InstitutionConfigurationProcessor to dispatch CreateInstitutionConfigurationCommand back through the full pipeline, which requires ROLE_MANAGEMENT. With no token present, AuthorizingStage rejected it and the whole bootstrap transaction rolled back with a ForbiddenException.

How does it address the issue?
TransactionHelper::beginTransaction() now sets a fully authorized console security token when none is present, so commands the pipeline dispatches internally during a console run are no longer rejected. Removed BootstrapCommandService::setToken(), an unused method from an earlier, unfinished attempt at this same fix.

Fixes #629

Test plan

  • phpstan clean
  • phpcs clean
  • full unit suite passing (new TransactionHelperTest included)
  • database integration suite passing
  • reproduced the exact issue against the released image, applied the fix in-place, confirmed middleware:bootstrap:identity-with-yubikey now succeeds and persists identity + institution config + vetted token correctly

Why is this change needed?
Prior to this change, console bootstrap commands (identity, yubikey,
sms, gssp, migrate) ran without a security token. Creating an identity
for a not-yet-configured institution triggers InstitutionConfiguration-
Processor to dispatch CreateInstitutionConfigurationCommand back
through the full pipeline, which requires ROLE_MANAGEMENT. With no
token present, AuthorizingStage rejected it and the whole bootstrap
transaction rolled back with a ForbiddenException.

How does it address the issue?
TransactionHelper::beginTransaction() now sets a fully authorized
console security token when none is present, so commands the pipeline
dispatches internally during a console run are no longer rejected.
Removed BootstrapCommandService::setToken(), an unused method from an
earlier, unfinished attempt at this same fix.

Refs: #629
@kayjoosten
kayjoosten requested a review from pmeulen July 29, 2026 09:07

@johanib johanib 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.

Security-focused review of the console token change. No reachable vulnerability found — TransactionHelper is only injected into console commands and AuthorizingStage is a pure role check. The two inline comments are least-privilege and defense-in-depth points on the new branch in beginTransaction().

Comment thread src/Surfnet/StepupMiddleware/MiddlewareBundle/Service/TransactionHelper.php Outdated
Comment thread src/Surfnet/StepupMiddleware/MiddlewareBundle/Service/TransactionHelper.php Outdated
Comment thread src/Surfnet/StepupMiddleware/MiddlewareBundle/Service/TransactionHelper.php Outdated
Why is this change needed?
The console token was set implicitly inside TransactionHelper::begin-
Transaction(), granting ROLE_SS, ROLE_RA, ROLE_MANAGEMENT and
ROLE_DEPROVISION to every caller. That conflated starting a database
transaction with authorizing privileged pipeline commands: any future
console command wired to TransactionHelper for its transaction
handling would silently inherit elevated roles it never asked for,
including ROLE_DEPROVISION, which nothing in these bootstrap flows
actually needs.

How does it address the issue?
Split the responsibility into TransactionHelper::authorizeConsole-
Context(), an explicit, opt-in call that each of the six bootstrap
console commands now makes before starting its transaction. Dropped
ROLE_DEPROVISION from the granted roles. beginTransaction() itself no
longer touches the token storage.

Refs: #629
@kayjoosten
kayjoosten merged commit f23f76f into main Jul 30, 2026
3 checks passed
@kayjoosten
kayjoosten deleted the feature/issue-629-bootstrap-yubikey-authorization branch July 30, 2026 08:09
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.

BootstrapIdentityWithYubikeySecondFactorCommand fails

2 participants