Skip to content

fix: allow MFA response reuse during tctl acl create/update - #69430

Queued
kimlisa wants to merge 3 commits into
masterfrom
lisa/fix-re-authn
Queued

fix: allow MFA response reuse during tctl acl create/update#69430
kimlisa wants to merge 3 commits into
masterfrom
lisa/fix-re-authn

Conversation

@kimlisa

@kimlisa kimlisa commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

The commands were failing (see error below) when admin-action is enabled because the API call performed multiple admin-protected writes (access_list and role).

...
ERROR: access denied
        mfa session data not found

Changelog: Fixed tctl acl create and tctl acl update failures when admin-action MFA is enabled.

Manual Test Plan

Test Environment

local - my user has both webauthn and otp registered

Test Cases

with admin-action enabled

  • successfully create a custom/jit/standing access list
  • successfully update a custom/preset list
  • successfully delete both custom and preset list (there is no bug with delete, but double checking)

without admin-action enabled

  • successfully create a custom/jit/standing access list
  • successfully update a custom/preset list
  • successfully delete both custom and preset list

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1ce8eb40de

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread tool/tctl/common/accesslist/command.go Outdated
func withResusableAdminActionMFA(ctx context.Context, client *authclient.Client) (context.Context, error) {
mfaResponse, err := mfa.PerformAdminActionMFACeremony(ctx, client.PerformMFACeremony, true /*allowReuse*/)
if err == nil {
ctx = mfa.ContextWithMFAResponse(ctx, mfaResponse)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve per-call MFA prompts for TOTP

When admin-action MFA users have only TOTP available, PerformAdminActionMFACeremony(..., allowReuse=true) can still return a TOTP response, but TOTP codes are single-use (checkOTP rejects the previously used token). Storing that response on the shared context makes multi-RPC create flows such as tctl acl create --access-type ... --members ... send the same OTP to both CreateAccessListWithPreset and the follow-up member upsert, so the later admin-protected call fails instead of prompting for a fresh code. Only keep this preflight response for MFA methods that are actually reusable, or clear it before subsequent RPCs that need a new TOTP.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

this should be okay, the admin-action is enabled when cluster is configured with second_factor: webauthn so PerformAdminActionMFACeremony will only return a webauthn response

The commands were failing when admin-action is enabled because
the API call performed multiple admin-protected writes
(access_list and role).
@kimlisa
kimlisa force-pushed the lisa/fix-re-authn branch from 1ce8eb4 to 9a1d39e Compare August 6, 2026 17:59
}))
}

func withReusableAdminActionMFA(ctx context.Context, client *authclient.Client) (context.Context, error) {

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.

Feels like this withReusableAdminActionMFA is something the MFA package should expose rather than having to hand roll at every call site.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

yeah i see it hand rolled in quite a few places... next time 😅

@github-actions github-actions Bot added size/sm tctl tctl - Teleport admin tool labels Aug 6, 2026

@kozadaev-tp kozadaev-tp 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.

LGTM - minor readability nit (optional)

Comment on lines +955 to +963
func withReusableAdminActionMFA(ctx context.Context, client *authclient.Client) (context.Context, error) {
mfaResponse, err := mfa.PerformAdminActionMFACeremony(ctx, client.PerformMFACeremony, true /*allowReuse*/)
if err == nil {
ctx = mfa.ContextWithMFAResponse(ctx, mfaResponse)
} else if !errors.Is(err, &mfa.ErrMFANotRequired) && !errors.Is(err, &mfa.ErrMFANotSupported) {
return nil, trace.Wrap(err)
}
return ctx, nil
}

@kozadaev-tp kozadaev-tp Aug 6, 2026

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.

[nit] I'd refactor the error handling for better readability. Feel free to ignore though.

Suggested change
func withReusableAdminActionMFA(ctx context.Context, client *authclient.Client) (context.Context, error) {
mfaResponse, err := mfa.PerformAdminActionMFACeremony(ctx, client.PerformMFACeremony, true /*allowReuse*/)
if err == nil {
ctx = mfa.ContextWithMFAResponse(ctx, mfaResponse)
} else if !errors.Is(err, &mfa.ErrMFANotRequired) && !errors.Is(err, &mfa.ErrMFANotSupported) {
return nil, trace.Wrap(err)
}
return ctx, nil
}
func withReusableAdminActionMFA(ctx context.Context, client *authclient.Client) (context.Context, error) {
mfaResponse, err := mfa.PerformAdminActionMFACeremony(ctx, client.PerformMFACeremony, true /*allowReuse*/)
if err != nil {
if errors.Is(err, &mfa.ErrMFANotRequired) || errors.Is(err, &mfa.ErrMFANotSupported) {
return ctx, nil
}
return nil, trace.Wrap(err)
}
return mfa.ContextWithMFAResponse(ctx, mfaResponse), nil
}

@kimlisa
kimlisa enabled auto-merge August 6, 2026 21:23
@kimlisa
kimlisa added this pull request to the merge queue Aug 7, 2026
Any commits made after this event will not be merged.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport/branch/v18 size/sm tctl tctl - Teleport admin tool

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants