Session protection

This page describes what protects your servers while a person or an AI agent works on them through Alpacon, and where that protection ends. It is written for the security reviewer who has to answer two questions: what stops a misbehaving agent or insider, and what fails open.

It describes Alpacon Cloud. Where a self-hosted deployment without Alpacon AI behaves differently, the section says so.

What a work session guarantees

Interactive access to a server goes through a work session. Nobody holds standing access: a person signed in to the console or the CLI can’t open a terminal, transfer a file or run a command without an approved, active session that covers it.

A session is a limit the request declares and an approver accepts:

  • Which features: the web terminal, file transfer, commands, port forwarding, the code editor and sudo, each declared separately.
  • Which servers: only the servers the session names.
  • For whom: only the person the session is for can use it.
  • Why: a written purpose, shown to the approver and kept with the record.
  • Until when: the session ends at a fixed time, and everything it opened closes.

Every operation is checked against the session when it happens, not only when the session is approved. An operation outside the session is refused, whatever the requester’s role.

Scope and intent

When a session is requested, Alpacon checks what it declares:

  • Features: an AI agent can’t declare the web terminal. An agent session is refused it when it is created, and again if anything tries to open one later.
  • Servers: the session lists the servers it may reach. A command or connection to any other server is refused.
  • Account: the session can name the server account to work as, under Connect as. An agent session runs only as the account approved for it; any other account is refused. No session can run as an account linked to another person, and no rule or setting lifts that stop.
  • Purpose: a session must state what it is for, in up to 2,048 characters. The purpose travels with the session: commands are judged against it, and work that drifts from it can be held (see Per-command checks).

While the session runs, each operation must pass these checks in turn: the session hasn’t ended, it is active, it includes the feature, the server belongs to it, and the caller is the person it is for. A Superuser working in the web console can act on another member’s session; nobody else can.

Approval

A new session waits for approval unless a rule admits it:

  • By default, a session a Superuser requests is approved at once. Every other session waits for one approver, and that includes every AI-agent session, whoever requested it.
  • Approvers are the people your access rules name. With no rule naming anyone, every active Superuser can approve.
  • Rules under Access rules, on the Opening a session tab, can allow a request, ask an approver or block it. An Allow rule for AI agents admits an agent session only when the session states a purpose.
  • Where approval comes from: an approval is accepted only from the web console or another channel registered for approving. The CLI, MCP client or token that made the request can’t approve it.
  • Self-approval: a requester may approve their own request unless the rule forbids it, and the record marks it as self-approved. When Alpacon can’t tell the agent’s client from the console, the person who requested an agent session can’t approve it.
  • Step-up: where an approval grants new authority, or your workspace requires MFA for approving, the approver confirms with a fresh MFA check. Signing in with MFA earlier doesn’t count.
  • Unanswered requests: an undecided request is canceled when its requested end passes or the pending limit is reached (24 hours by default), whichever comes first.
  • Changes: an extension goes through the same rules as a new session. Changing an agent session’s purpose, or adding a server to it, needs approval again.

The approval check compares the request with your rules; it does not inspect what the session will do. See What Alpacon checks, and what it doesn’t.

Per-command checks

Each command sent in a work session, through the command API or alpacon exec, is judged by Alpacon AI before it reaches the server. The AI rates its risk, approves or rejects it, and compares it with the session’s purpose. What happens next, for a command in a work session (a service token’s command outside a session is settled differently; see Access outside a work session):

The AI’s judgmentA person’s commandAn AI agent’s command
ApprovedRunsRuns, unless one of the holds below applies
Approved, but the AI is not confidentRunsHeld for an approver
Off the session’s purposeHeld for an approverHeld for an approver
RejectedHeld for an approver, who sees why the AI rejected itHeld for an approver, who sees why the AI rejected it
  • Servers that always need a person: an agent’s command to a server in the agent-approval-required server group is always held, whatever the AI says.
  • Held commands wait in Approvals and notify the approvers. If the approver approves, the command runs; if they reject it, or nobody decides within 24 hours, it doesn’t. If nobody other than the requester could approve it, the command is refused at once.
  • Your rules: rules on the Running a command tab, matched on requester, server group and the AI’s rating, can hold, allow or block a command in place of these defaults. No rule lets through a command the AI rejected. A command a rule blocks is refused.
  • Scripts: a file run as a command must pass the AI’s review. A script an approver already cleared runs again without a new hold, as long as it hasn’t changed.
  • Commands typed in a terminal: commands typed in a Websh terminal are not judged one at a time; their sudo is (see sudo and run-as). The whole session gets an AI analysis after it ends.
  • Advisory workspaces: a workspace in Advisory execution control records every judgment but holds and refuses nothing because of it. Commands run at once, and new sessions are admitted without approval.

You see the result on the command: its status, the AI’s rating and, for a held or refused command, the reason. See Commands.

sudo and run-as

sudo needs the session to declare the sudo feature, for every requester, Superusers included. Then each use of sudo is judged on its own, by the risk the AI rates for the elevated command. This table is that per-use check; a command an approver already approved is the exception below:

RatingA personAn AI agent
Info, LowAllowed, after MFAAllowed
MediumAllowed, after MFAHeld for an approver
HighHeld for an approverHeld for an approver
Critical, or not ratedRefusedRefused
  • MFA: a person proves they are present with a recent MFA check. An agent can’t, so for an agent the session’s approval stands in for it. A command that runs without a terminal can’t ask for MFA; it is refused with SUDO_PRESENCE_REQUIRED, and you verify and run it again.
  • Holds: a held sudo creates an approval request. Once it is approved, run the command again.
  • Approved commands: when a person approves a held command, that approval also covers each sudo written in the command’s line, at any rating, Critical included. It doesn’t override the session’s sudo feature, the account’s authority, or a workspace rule that blocks the sudo. If you approved your own command, you still confirm with MFA. A sudo the approver never saw in the line gets the per-use check above.
  • Tightening only: your rules on the Using sudo tab, and a session’s own sudo settings, can turn an allow into a hold. A sudo the AI judges off the session’s purpose is held. No rule can allow a Critical sudo; only a person’s approval of the command that contains it can.
  • Session sudo policies: a session can carry its own sudo policies, bound to its servers and its time window. An agent session that carries them always needs a person to approve it.
  • Run-as: sudo -u, su or runuser into an account linked to another person is refused, for administrators too, and is never offered for approval. A switch whose target account can’t be read is refused the same way. root, and accounts not linked to anyone, follow the rules above.

The codes on a refused sudo and what to do about each are in PAM issues.

Time bounds

  • Workspace maximum: a session can’t be longer than the workspace’s Maximum session duration, 4 hours by default. A Superuser sets it in workspace settings, between 5 minutes and 7 days. A request for longer is refused, not shortened.
  • Scheduled start: a session can start at a future time. It does nothing until then.
  • Expiry warning: the requester and the person the session is for get a notice to extend it a few minutes before it ends.
  • Extension: a session that has started can be extended, with a reason, through the same approval rules. The new end can’t be more than the workspace maximum from the moment you ask.
  • At the end time: every new operation is refused at once with work_session_expired.

Ending a session

How it endsWhoFrom
CompleteThe person the session is for, or a Superuser, with Complete sessionAn active session
RevokeA Superuser, with Revoke sessionAn approved or active session
ExpireAlpacon, at the end timeAn approved or active session
User removed from the workspaceAlpacon, when the user is deletedEvery approved or active session for that user

Each of these four closes everything the session opened:

  • Terminals: open Websh terminals close, and the browser shows why.
  • Tunnels: port forwards and code editor connections close.
  • File transfer: open WebFTP sessions close.
  • Queued commands: commands not yet delivered to a server are cancelled, including commands held for approval.
  • sudo policies: the session’s own sudo policies stop applying. They stay in the record.

Pending change requests on the session are cancelled too. Completing or revoking closes everything at once; an expired session’s open connections close within a few minutes, and nothing new is allowed in the meantime.

A pending session that is cancelled or rejected never opened anything, so there is nothing to close.

Deactivating a user, rather than removing them, closes their open terminals and file transfers at once, and they can’t sign in again to use their sessions.

When Alpacon AI is unavailable

If Alpacon AI can’t answer, Alpacon doesn’t wait indefinitely. What happens depends on what was asked:

  • Commands in a session run without the AI’s approval and are marked Skipped in command history. Rules that don’t depend on the AI still apply: a command your rules hold for its requester or server is still held, and so is an agent command to a server in agent-approval-required, or a command the AI already found off-purpose in this session.
  • Files run as commands are refused, because a script can’t run without the AI’s review.
  • Commands sent with a service token are refused, because their pre-approval can’t be checked.
  • sudo in a command is refused, since the command has no rating, unless the session carries a sudo policy that skips MFA.
  • sudo in a Websh terminal falls back to the normal sudo checks: a matching sudo policy, an approver where your rules ask for one, and MFA.
  • Session approval doesn’t use the AI, so it works as usual.

On a self-hosted deployment without Alpacon AI, commands run without a judgment and are marked Skipped, files can’t be run as commands, sudo in a session follows your sudo policies and MFA, and sudo with a service token is refused.

Access outside a work session

Commands run inside a work session, or through a service token under its access-control rules. The one exception is a personal API token that already runs commands, described below. Three kinds of credential reach the API without a work session, and a security review should list them:

  • Service tokens: automation tokens issued to an application. A service token works within its scopes and its server, command and file access-control rules, its allowed IP ranges and hours, and its rate limit. Outside Advisory, an AI rejection of a service token’s command is recorded and the command still runs, unless the AI rates it Critical; your rules can tighten that. On Alpacon Cloud, service-token sudo is allowed below Critical, including unassessed commands, and refused at Critical unless the workspace is Advisory. In Advisory, it is not refused for risk at any level, and the decision is recorded. Outside Advisory, a workspace token_exec rule can tighten the risk threshold. The workspace sudo setting must be on; otherwise sudo is refused with workspace_sudo_with_mfa_disabled. On a default self-hosted install, every service-token sudo is refused. Sudo policies do not apply to service tokens; they do apply to personal API tokens. See Service tokens.
  • Registration tokens: used once to register a server. They can only register servers.
  • Personal API tokens: New personal API tokens cannot hold command-execution or file-transfer scopes. Existing tokens with those scopes keep working without a work session. Use a service token for automation and CI.

None of these can open a Websh terminal, the code editor or a WebFTP session; those need a signed-in person. For automation, use service tokens: their limits are set by an administrator and every use is recorded under the application.

External access is detected, not blocked. Logins that reach a server without Alpacon (SSH, the local or cloud console, su) are outside any work session. With Direct-login detection turned on, which is off until someone turns it on, Alpacon records each one and asks a reviewer about the ones you haven’t marked as expected. It never stops the login. To keep sudo inside Alpacon, turn off Sudo outside the web terminal. See External access.

What is recorded

  • Terminal sessions: Websh sessions are recorded, with credentials masked. On a paid plan you can replay a whole recording; on the Free plan you see only its opening. See Session recordings.
  • Commands: each command with its requester, session, AI judgment and output. See Commands.
  • File transfers: each upload and download, including refused ones, with its session.
  • sudo: each allowed and refused sudo, with the reason. See Privilege elevation.
  • Approvals: who asked, who decided, when, and whether it was self-approved.
  • AI analysis: a completed, expired or revoked session gets an AI risk analysis of what took place. See After a session.
  • Direct logins: when detection is on, logins that bypassed Alpacon.

Audit records are read-only. How far back you can look depends on your plan; see the pricing page.

Known limits

  • The AI’s judgment is the main per-command check. When it is unavailable, session commands run marked Skipped, and only rules that don’t depend on the AI still hold them.
  • Terminal commands aren’t judged one at a time. In a Websh terminal only sudo is judged as it runs; the rest is recorded and analyzed after the session. Agents can’t open a terminal.
  • Advisory turns off holds. In an Advisory workspace, nothing is held or refused because of a judgment, and sessions are admitted without approval.
  • Service tokens work without a session, within their own limits. A service token’s command the AI rejects still runs unless it is rated Critical.
  • Direct logins aren’t blocked. Detection is off by default and records only.
  • The agent’s name is self-reported. See What Alpacon checks, and what it doesn’t.
  • Self-approval is allowed by default. Forbid it in the rule where it matters.
  • A delivered command runs to the end. Ending a session cancels commands not yet delivered; one already running on the server is not stopped.
  • Alpacon is not a sandbox or an EDR. It controls who reaches a server and what they run through Alpacon; it doesn’t contain what a permitted command does on the server.
Last updated: