sudo with MFA
sudo with MFA lets you run sudo commands in Websh terminal sessions without permanent sudo privilege. When you enter a sudo command, MFA verification is required before the command executes.
This page covers interactive terminal sessions. For sudo in an automated pipeline running under a token, see Command patterns and sudo—a token is authorized differently and sudo policies do not apply to a service token.
Requirements
- Alpamon 1.3.2 or later installed on the target server
- Sudo through Alpacon turned on at the top of the Sudo tab of Access rules under Policies (this automatically installs the required PAM module on servers)
Enable sudo with MFA
- Go to Policies > Access rules in the sidebar and open the Sudo tab (see sudo and root access)
- Turn on Sudo through Alpacon
- The PAM module is automatically installed on the servers running Alpamon 1.3.2+ that are connected at that moment
A server that is offline at that moment does not receive the install, and there is no automatic retry once it reconnects. Install alpamon-pam on that host yourself—see The user has no sudoers rule.
On Alpacon Cloud, only a Superuser can change the switches on the Sudo tab and the MFA re-check window. Staff users can use sudo with MFA after it is enabled but cannot change this setting. On a self-hosted deployment without Auth0, Staff can change Allow direct root login and turn Block sudo outside Websh off, and nobody can change Sudo through Alpacon: it stays as stored.
On a deployment that can’t ask for MFA (self-hosted, without Auth0), the Sudo through Alpacon switch is shown but can’t be changed, and the value already stored keeps applying. See Deployments without Auth0.
sudo with MFA works independently from the Allow direct root login setting. Even when direct root access is disabled, users can still run sudo commands through sudo with MFA.
Disabling sudo with MFA
Turning Sudo through Alpacon off on the Sudo tab of Access rules takes effect immediately and changes behavior across the whole workspace:
- Alpacon stops authorizing
sudo. Everysudorequest that reaches Alpacon is refused, on every server, whether or not the PAM module is installed there. The denial carries the codeWORKSPACE_SUDO_WITH_MFA_DISABLED—see “Alpacon denied this sudo command”. A system account that already had its own sudoers permission before Alpacon managed the host keeps it. - Your servers are left alone. Nothing is uninstalled and no command is sent to any server. The
alpamon-pampackage stays installed, and keeps its configuration and the sudoers rule it manages, but it has no effect while the setting is off. - Requests already awaiting approval are not rejected. They stay in the approval queue, but approving one no longer lets the
sudocommand run, and the authorization behind it expires on its own deadline. - “Block sudo outside Websh” is turned off. Because that setting depends on sudo with MFA, it is switched off automatically.
Disabling is a policy change only—it stops Alpacon from authorizing sudo and changes nothing on your servers. That makes it fully reversible: turn the setting back on and sudo with MFA works again, with no repair needed on the servers themselves.
Turning Sudo through Alpacon back on authorizes sudo again immediately. It also installs alpamon-pam on every server that is connected at that moment, so any server still missing the package picks it up.
How it works
When you run a sudo command in the terminal:
- Enter a
sudocommand (for example,sudo systemctl restart nginx). - An MFA verification required overlay appears in the terminal. Click Click to verify to open the verification window.
- After you complete MFA, the command executes.
- Subsequent
sudocommands don’t require MFA again until the sudo with MFA timeout expires. This duration is set by workspace administrators in Server access policies.
If verification fails or the MFA session expires, the terminal asks you to re-run the command to authenticate again.
Which sign-ins can complete the verification
Only a person signed in interactively can complete the sudo MFA verification: in the web console, or in the CLI after a browser sign-in with alpacon login. A credential that carries no MFA of its own can’t complete it, even if the person behind it verified somewhere else: a personal API access token, a service token, or an AI agent’s MCP connection.
If the CLI is signed in with an API token (alpacon login -t), a sudo that asks for MFA stops with “Sudo MFA cannot be completed with this credential”. Sign in again with alpacon login, without -t, and re-run the command. For unattended work that needs sudo, use a work session with MFA-bypass sudo policies (see alpacon work-session create --sudo), or a service token as described in Command patterns and sudo.
Deployments without Auth0
sudo with MFA needs Auth0 to verify you. On a self-hosted deployment without it, a sudo that would ask for MFA is refused right away with SUDO_STEP_UP_UNAVAILABLE instead of opening a prompt that can’t complete. The way to elevate there is a work session with MFA-bypass sudo policies (see alpacon work-session create --sudo).
Waiting for approval
When you run an interactive sudo in a Websh terminal and the command needs an approval, the terminal waits for the decision instead of failing. A command needs an approval when a rule requires one (SUDO_APPROVAL_REQUIRED), when it deviates from the purpose of its work session (SUDO_INTENT_DEVIATION), or when you have no standing authority for it (SUDO_NO_AUTHORITY). In a workspace with Advisory execution control, a command with no standing authority is refused immediately instead.
For a self-hosted site, terminal waiting requires Alpacon 2.44.0 or later, Alpamon 2.8.4 or later, and alpamon-pam 1.2 or later. On older versions, sudo behaves as described in When sudo is refused.
What you see
- The terminal prints
Waiting for approval (request <request ID>, expires in <minutes>m) .... Thesudocommand stays blocked until an approver decides or the wait ends. It waits for up to 5 minutes, or less when the approval window is shorter. - When an approver approves:
- If you are actively at the console, the command continues at once.
- Otherwise an MFA step-up appears in the console. Complete it, and the command runs.
- If an approver rejects or you withdraw the request, the terminal prints that it was rejected and the command does not run.
- If nobody decides before the wait ends, the terminal prints that the request stays open and asks you to run the command again once it is approved (
SUDO_APPROVAL_PENDING). This also happens if approval is given but the MFA step is not finished before the wait ends. The request is not lost. Once it is approved, run the same command again.
To stop waiting, press Ctrl+C. The terminal prints “You stopped waiting. The request stays open; run the command again once it’s approved (SUDO_APPROVAL_PENDING).” The request stays open, so you can run the command again after it is approved.
If you run the same sudo command from another terminal while one is already waiting, the second one is denied with SUDO_APPROVAL_ALREADY_WAITING. Use the terminal that is waiting, or press Ctrl+C there first.
The same command means the same command for the same target account and the same -u run-as account: sudo -u alice cmd and sudo -u bob cmd are different requests and do not block each other.
When nothing waits
The terminal does not wait, and behaves as before, in these cases:
- A Websh session outside a work session, where
sudois denied as before - Non-interactive
sudo, such assudo -n,sudo -Sorsudo -b - AI agents and service tokens
- Advisory execution control without standing sudo authority, where
SUDO_NO_AUTHORITYis returned immediately, no approval request is filed, and the terminal does not wait. Ask a workspace owner for a standing sudo grant under Server access policies - Commands that are denied outright, such as a command on another person’s account, or one blocked by a bypass or scope denial
- A request nobody else can approve, where only you could approve it, is refused at once with
APPROVAL_NO_OTHER_APPROVER; add a second approver or an auto-approve rule
For approvers
Nothing changes on the approver side. The request appears on the Approvals page as before, and you review it as described in Reviewing requests.
When sudo is refused
When Alpacon refuses a sudo command in a Websh terminal, the command does not run and the terminal prints a line with a code in parentheses:
Alpacon denied this sudo command (SUDO_APPROVAL_REQUIRED).The three codes below are about the command itself, and what to do about them here applies to Websh. A command run through a token or alpacon exec is handled differently; see Command patterns and sudo. For the other codes, see “Alpacon denied this sudo command”.
SUDO_APPROVAL_REQUIRED
This command needs a person to approve it, and Alpacon has already sent the approval request. Someone else in your workspace who can approve requests sees it on the Approvals page. With the agent versions in Waiting for approval, the terminal waits for the decision instead of printing this line. Otherwise, once it is approved, run the same command again. A request nobody decides expires after a few minutes.
SUDO_INTENT_DEVIATION
You are in a Websh session that belongs to a work session, and the command doesn’t match the purpose written for that work session. Alpacon has sent an approval request, as with SUDO_APPROVAL_REQUIRED, so you can wait for it to be approved and run the command again (or, with the agent versions in Waiting for approval, let the terminal wait for you). If your work has moved on from the original purpose, request a new work session that describes it and run the command there.
SUDO_RISK_DENIED
Your workspace does not allow this command to run with sudo, either because its access rules block it or because the command was judged too risky. There is no request to approve, and running the same command again gives the same result. Ask a Superuser, who can review the rules on the Access rules page under Policies.
Sudo policies and grants
How a sudo command is authorized depends on your workspace’s rules on the Sudo tab of Access rules under Policies:
- Sudo policies — administrators can pre-authorize specific commands for certain users or servers. A policy bound to a work session can allow MFA bypass, so a non-interactive caller (for example, an AI agent running
exec) can run those exact commands without an interactive MFA prompt. - Approval — a sudo request can be authorized by an administrator’s approval.
Every authorization—by direct permission, policy, or approval—is recorded. Review it in Sudo history.
Compatibility with sudo-rs
Ubuntu 25.10 and later (including 26.04) ship sudo-rs as the default sudo. sudo with MFA works on these hosts and requires the alpamon-pam package version 1.1.2 or later—Alpacon detects sudo-rs and authorizes sudo commands through PAM.
With classic sudo (1.9+), Alpacon also registers a separate sudo approval plugin in /etc/sudo.conf. sudo-rs has no plugin interface, so that plugin is not used and does not appear in /etc/sudo.conf on sudo-rs hosts. This is expected and not a misconfiguration.
When a sudo command is denied on a sudo-rs host with no terminal attached (for example, through alpacon exec), sudo-rs cannot display the denial reason and reports A terminal is required to authenticate instead. See PAM and sudo issues to find the actual cause.