Agent access security
How Scipio 4.0 secures agent access through MCP: the token model, permissions, policy, audit, and expiry.
This page describes how Scipio 4.0 secures agent access through MCP, and what an operator must do before and during production use. Read Agent quickstart for the setup steps.
Principles#
- A token is a user login. An agent has exactly the permissions of that user. No permission comes from the token itself.
- Default deny. A call passes only when every gate in the policy engine allows it.
- One rule for every endpoint. The hub and the application endpoints apply the same policy.
- Everything is audited. Every tool call, denied or not, writes one
McpAuditLogrow. - Executable code is a separate permission. CMS templates and scripts need
MCP_CODE_WRITE.
Permissions and groups#
| Permission | Grants |
|---|---|
MCP_ACCESS | Use any MCP endpoint. Required for every token user. |
MCP_GATEWAY | Call any service through scipio_service with action call (still subject to the policy engine). |
MCP_ENTITY_READ | Read entities outside a server’s allowlist through scipio_entity with action find. |
MANUFACTURING_FLOOR | Declare, scan, start and complete production run tasks without MANUFACTURING_UPDATE. |
MCP_MAIL_SEND | Send a mail from a template through mail_send_template. Granted to FULLADMIN. |
MCP_ENTITY_WRITE | Write entities through the entity tools (also needs ENTITY_MAINT). |
MCP_ADMIN | Manage tokens of any user, view the audit log, reload the registry, run services of components without a webapp. |
MCP_CODE_WRITE | Write CMS FreeMarker templates, Groovy scripts and asset templates. Remote code execution by design. |
Seed groups:
SCIPIO_AGENT(userscp-agent):MCP_ACCESS,MCP_GATEWAY,OFBTOOLS_VIEW,CMS_VIEWand_VIEWon every main application. Read-only by default.SCIPIO_CUSTOMER_AGENT:MCP_ACCESSonly. For shop customers who use an assistant on/shop/mcp.SCIPIO_FLOOR:MCP_ACCESS,OFBTOOLS_VIEW,MANUFACTURING_VIEWandMANUFACTURING_FLOOR. For shop floor device tokens, which declare, scan, start and complete production run tasks and write nothing else.FULLADMIN: everyMCP_*permission, includingMCP_CODE_WRITE.
Give an agent a dedicated user per purpose. Grant _UPDATE only for the
applications the agent must change. Do not reuse a human administrator’s
login.
The policy engine#
McpPolicy decides every call in this order. The first failing gate
denies the call.
- Server access: token allowed for the webapp, user holds
MCP_ACCESS, user holds every base permission of the webapp at_VIEW(for exampleOFBTOOLS_VIEWandORDERMGR_VIEW). The hub needsMCP_ADMINorOFBTOOLS_VIEW. - Tool access: a read-only token may call read-only tools only. A tool’s
permissionattribute is checked when set. - Service deny lists:
mcp.service.deny(global), the server’sserviceDeny, andmcp.service.adminOnly(needsMCP_ADMIN). - Gateway permission: a direct service call needs
MCP_GATEWAY. - Read-only classification: an entity-auto create, update, delete or
expire is a write. A tool’s own
readOnlyflag never widens a write service into a read. - Service permissions: a service that declares
permissionsorpermissionServiceenforces them itself. - Component rule: an unguarded service needs the base permission of the
component that owns the service:
_VIEWfor a read,_UPDATEfor a write, on every webapp base except the genericOFBTOOLS. A component without a webapp needsMCP_ADMIN, except the components listed inmcp.gateway.openComponents(defaultcommon), which use the endpoint’s base permission.
Hand-written tools on a webapp without a base permission (the shop) are
allowed only on a server with allowAnonymous=true; every other
permission-less webapp fails closed.
Tokens#
- Format
scp_<id>_<secret>_<crc>. Only the SHA-256 hash is stored. The secret is shown once. - Expiry: default
mcp.token.defaultExpiryDays(90), maximummcp.token.maxExpiryDays(365). A token without an expiry date is rejected unlessmcp.token.allowNoExpiry=true. mcp.token.denyUsers(defaultsystem,anonymous) can never own or use a token.webappslimits a token to a list of endpoints.readOnly=Yblocks every write tool.remoteAddrAllowlimits a token to addresses or CIDR blocks.maxOrderAmountcaps the total of an order placed throughshop_cart:checkoutororder:create.- Revoke a token on Webtools > Agent Access > Tokens. Revocation is immediate.
Transport and input limits#
- HTTPS is required.
X-Forwarded-Protois honoured only frommcp.trustedProxies. Originmust be inmcp.origin.allow(default: no browser origin passes).Hostmay be limited withmcp.host.allow.- Body at most
mcp.request.maxBytes(1 MB), JSON nesting at most 64, batch at most 20 requests, string 64 KB, array 1000 items, list limit 500, result 200 000 characters. - Rate limits:
mcp.rateLimit.perMinuteper token,anonymousPerMinuteper address,failedAuthPerMinuteper address,maxConcurrentslots per token.
Data protection#
mcp.entity.deny:UserLogin*,*Password*,*CreditCard*,*EftAccount*,*PaymentGatewayConfig*,*Secret*,Mcp*,Security*,SystemProperty,Tenant*,*Keystore*,X509*,JobSandbox*. These tables are never readable or writable through the entity tools, for any user.mcp.redact.fieldsandmcp.redact.patternsmask sensitive values in results, argument echoes and audit rows. A protected field may not be used in a condition, a selection or an ordering ofscipio_entitywithactionfind; this closes the value-guessing side channel.- Audit rows store redacted arguments, a bounded result
(
mcp.audit.resultMaxChars) for idempotent replay, and aREPLAYstatus when a stored result is returned.
Operations checklist#
Before production:
mcp.allowInsecure=false;mcp.trustedProxiesset when a proxy terminates TLS.DevAuthEvent(developer auto-login) removed or gated; see the release checklist.- The
smoketoken and every test token revoked;scp-agentgiven only the groups you need. mcp.gateway.allowUnguardedreviewed. Set it tofalseto allow only services that declare their own permissions and the tools that profiles declare explicitly.mcp.tool.disableset for tools you do not want, for examplescipio_entitywithactionstore.- Run
tools/mcp-test.sh -t <admin> -a <scp-agent> security skillsand confirm 0 failures.
During operation:
- Review Webtools > Agent Access > Audit daily. Filter by
DENIEDto see blocked attempts. - Rotate tokens before they expire: create a new one, update the client, revoke the old one.
- After a change to a profile, an extension or a skill, click “Reload agent registry”.
Incident response:
- Revoke the token (Tokens page). The next request fails with
401. - Disable the user login when the account itself is suspect.
- Read the audit rows of the token:
tokenId,toolName,argsSummary,remoteAddr. - Undo data changes with the normal application tools; the audit row names the service.
Known limits in 4.0#
- No OAuth. Bearer tokens only.
- No server-initiated push (SSE) and no elicitation. Confirmation is a
client-side hint (
_meta.requiresConfirmation). - Rate limits are per JVM, not per cluster.
- An agent that reads business data can still be misled by adversarial text inside that data. The skills tell the agent to treat returned data as data, not instructions; the client must enforce it.