BTP Administration¶
Operate an ARC-1 deployment on SAP BTP Cloud Foundry after the first successful read. This page covers the controls shared by single-target and multi-target deployments. For initial installation, start with BTP Cloud Foundry Deployment. For registry reason codes and the shared-Basic exception, use Multi-Target Administration.
Know the boundary you operate¶
BTP global account
└── subaccount
├── trust and subaccount destinations
└── Cloud Foundry org
└── space
├── ARC-1 application and route
└── XSUAA, Destination, and Connectivity service instances
ARC-1 multi-target v1 reads subaccount destinations. A CF space is not a hard target-inventory boundary. Another application with suitable Destination Service access in the same subaccount may resolve the same subaccount destinations. Use a dedicated subaccount when destination inventory itself requires strong isolation.
SAP Multi-Target Application (MTA) packaging and ARC-1 multi-target routing are unrelated:
- the SAP MTA is the
.mtardeployment format described bymta.yaml; - ARC-1 multi-target is the optional runtime mode that exposes several SAP systems/clients.
Responsibilities¶
One person may hold several roles in a small landscape, but each handoff should remain explicit.
| Work | Typical owner |
|---|---|
| Entitlements and subaccount isolation | BTP subaccount administrator |
| MTA deployment, route, app environment, and bindings | CF Space Developer |
| Destination fields and Basic credentials | Destination Administrator |
| XSUAA role collections and assignments | User and Role Administrator |
| Cloud Connector mappings, trust, and resource allowlist | Cloud Connector administrator |
| STRUST, CERTRULE, ICM/SICF, SU01, and SAP roles | SAP Basis/security |
| MCP client acceptance and service ownership | ARC-1 service owner |
Do not solve a missing permission by giving all owners broad BTP or SAP administration. In particular, anyone who can read or change a Basic destination is a credential administrator for its shared SAP user.
Configuration ownership¶
For the OAuth callback-policy upgrade, follow XSUAA upgrade guidance. It requires a full MTA deployment; an app restart alone does not update the XSUAA service policy.
Use one source of truth for each kind of value:
| Location | Put here | Avoid here |
|---|---|---|
mta.yaml |
Versioned safe product defaults, resources, bindings, role collections | Customer destinations and secrets |
Customer mta-overrides.mtaext |
Durable route, instance count, named single target, and application safety ceilings | Destination credentials |
| BTP subaccount destination | URL, SAP client, identity mode, Cloud Connector routing, and target-local multi-target data/SQL policy | Global write or authorization policy |
cf set-env |
Stable ARC1_DCR_SIGNING_SECRET; controlled emergency overrides |
Preferred desired state for ordinary non-secret values |
VCAP_SERVICES |
Platform-generated binding credentials | Manual edits or copies into support tickets |
| Cloud Connector and SAP | Network exposure, certificate trust/mapping, SAP authorization | ARC-1 OAuth roles |
Keep the customer .mtaext in an access-controlled configuration repository. It is ignored by the
ARC-1 repository by default. Never edit generated mtad.yaml; rebuild it from the reviewed source
descriptor and extension.
An MTA extension can add or override values but cannot remove a base property. Use an explicit off
value such as "false" when disabling something inherited from mta.yaml. A direct cf set-env
change is useful for an incident, but the next MTA deployment reapplies every property declared by
the descriptors. Reconcile the desired-state file after the incident.
Change and restart matrix¶
Use the smallest action that makes the change effective and preserves desired state.
| Change | ARC-1 action | Notes |
|---|---|---|
| Add/remove a multi-target destination | cf restart arc1-mcp-server |
Registry discovery is a startup snapshot; no MTAR rebuild |
Change destination URL, client, alias, description, identity mode, arc1.*, or location ID |
Restart every app instance | Calls fail closed on detected drift until restart |
Change only a discovered multi-target Basic destination User/Password |
None | Resolved on the next protected request; verify a safe read |
Change a single-target SAP_BTP_DESTINATION credential |
Restart every app instance | The single-target destination is resolved at startup; restart promptly to avoid retrying an obsolete password |
| Change SU01 e-mail, CERTRULE/VUSREXTID, or SAP role | None | Retry with the same MCP session; PP failures are not negatively cached |
| Change Cloud Connector mapping/resource/trust | Usually none | Retry after save; restart ARC-1 only if target configuration also changed |
| Change STRUST or ICM/profile setting | SAP/ICM action as required | Follow the SAP Basis change procedure |
| Change a role assignment | New OAuth login/token | Restart clients that cache the tool catalog |
Change .mtaext, service resources, binding, app memory, or instance count |
Build and deploy MTA | This is durable desired-state change |
Change a runtime environment variable with cf set-env |
cf restart normally; cf restage when staging must rerun |
Reconcile non-secret values into .mtaext |
| Change code, Node dependencies, or buildpack inputs | Rebuild and deploy | Verify the exact deployed version |
Rotate ARC1_DCR_SIGNING_SECRET |
Restart/restage and reauthenticate every client | Intentional global DCR revocation |
cf restart reuses the staged droplet. cf restage stages a new droplet and is appropriate when
buildpack or staging inputs changed. Destination restart behavior is an ARC-1 registry property, not
a general Destination Service limitation.
Role and user administration¶
Keep these XSUAA concepts separate:
| Concept | Meaning |
|---|---|
| Scope | Capability checked by ARC-1, such as read, data, or sql |
| Role template | Application declaration that groups scopes |
| Role | XSUAA instance-specific role created from a template |
| Role collection | Subaccount bundle that administrators assign |
| Assignment | User/group grant that produces scopes in a new token |
The MTA creates eight role collections with the CF space suffix: seven functional collections
(for example ARC-1 Viewer (dev)) plus ARC-1 All Targets (dev). Leave All Targets unassigned
unless explicitly approved; it grants all current and future targets when filtering is enabled.
After every new or upgraded XSUAA deployment:
- Open BTP Cockpit → Security → Role Collections.
- Confirm all expected
ARC-1 … (<space>)collections exist. - Open each collection and confirm its Roles tab contains roles for the current
arc1-mcp-<space>!t...application identifier. - For single-target or standard multi-target access, assign the least-privilege collection before the user's first MCP login. For target-filtered access, follow the target-role setup order: verify enforcement and active destinations before assigning restricted users.
- Have the user sign in again and restart/reconnect the MCP client if its tool catalog is cached.
An older or recreated XSUAA instance can leave same-name collections with empty/orphaned roles. First inspect and reconcile the collection with its owner; empty roles alone do not justify deletion. Only when the owner confirms an orphaned collection requires replacement, record its roles, user/group assignments and IdP mappings before removal. Then perform the reviewed MTA deployment, inspect the recreated roles, restore the approved assignments/mappings and verify a fresh user grant. This is not a generic login fix and does not require deleting XSUAA.
When changing the roles contained in a predefined collection, prefer a newly named/versioned collection: deploy it, inspect it, assign users/groups, reauthenticate and test, then remove old assignments. Renaming a collection does not carry user assignments forward.
See XSUAA Setup for the complete scope matrix, OAuth flow, IdP-origin handling, and client configuration.
DCR signing secret¶
ARC-1 Dynamic Client Registration is stateless. Ordinary cf restart, cf push, cf restage, or
horizontal scale does not lose registrations while every process uses the same signing key.
Set a dedicated key once so XSUAA binding-secret rotation does not invalidate cached MCP
client_ids:
# Run in a protected operator shell. Do not paste the value into tickets or chat.
cf set-env arc1-mcp-server ARC1_DCR_SIGNING_SECRET "$(openssl rand -base64 48)"
cf restage arc1-mcp-server
Treat this as a deployment secret:
- never commit it, add it to
.mtaext, or package it in the MTAR; - limit CF roles that can inspect app environment;
- never attach unredacted
cf envoutput to an issue; - store a recoverable copy in the customer's approved secret-management process; and
- rotate it only as a security event, because rotation invalidates every stateless DCR client.
With a dedicated secret, rebinding XSUAA no longer revokes DCR registrations by itself. Rotate
ARC1_DCR_SIGNING_SECRET when global DCR revocation is intended. ARC-1 currently consumes it as an
environment variable; sufficiently privileged CF operators can therefore read it. A bound/file
secret is a future hardening item, not a property that documentation can provide today.
Audit Log delivery evidence¶
Verify a known event end to end; a startup message only confirms binding fields.
- Prepare an approved Audit Log Viewer or
auditlog-managementreader (plandefault) for subaccount-wide API retrieval. Follow SAP's retrieval setup. Prefer X.509/mTLS credentials, keep keys outside tickets/source control, and recreate reader bindings/keys at least every 90 days or earlier on expiry. A client-secret key is an alternative where credential policy permits it. - Make one successful
SAPReadcall withtype="SYSTEM"through the intended ARC-1 endpoint. Record the UTC time, authenticated caller and CF space GUID (cf space <space-name> --guid). Runcf logs arc1-mcp-server --recentand record the matching tool event's request ID.REQ-nis process-local and repeats across restarts/instances; it is not a globally unique lookup key. - In the Viewer, or with a valid OAuth token in the retrieval API, search a narrow
UTC window around that call.
SAPReadusesaudit.data-access, matching this example (other tools can use different categories):
GET <url>/auditlog/v2/auditlogrecords?time_from=2026-09-17T07:00:00&time_to=2026-09-17T07:05:00&category=audit.data-access
Authorization: Bearer <token>
<url> comes from the reader credentials. UTC times use YYYY-MM-DDTHH:MM:SS;
without a time filter the API searches the previous 30 days. Pages contain up
to 500 records: URL-encode Paging: handle=… as the next request's handle
parameter. HTTP 204 means an empty result. Back off on 429. If category
filtering returns 501 for your landscape, omit it and filter locally. See
SAP's linked API contract for current limits.
4. Match object.type = "MCP Tool Call", tool, user, space_id, request ID and the
UTC window together. Use target when present; a space can serve several SAP
systems. Invocation records include redacted args (cut after 500 characters
with ... appended); completion records carry the outcome. Retain the matched
evidence privately. If these fields do not distinguish concurrent requests,
repeat with a fresh known call in a quiet window.
Delivery is asynchronous: one eu10 check took 11 minutes, which is an observation,
not a delivery guarantee. Recheck the same known event before diagnosing loss.
Monitor known traffic and certificate expiry; a quiet server alone is not evidence
of failure. ARC-1 emits throttled BTP Audit Log delivery failed warnings but does
not configure an external alert for you. The reader does not enable writing:
ARC-1's sink requires the separate auditlog premium binding.
Audit Log certificate rotation¶
The optional Audit Log binding certificate does not renew inside a running process. Before its
configured validity ends, unbind arc1-auditlog from arc1-mcp-server during a maintenance window.
For MTA deployments, redeploy the reviewed MTAR with the same extension to recreate the binding;
for direct cf push, repeat SAP's
X.509 binding procedure
and restage. Check the startup log and delivery of a known audit event afterward (see
Audit Log delivery evidence). Rotation recreates only the binding;
the instance keeps its X.509 configuration. Track the expiry in your monitoring or
calendar and verify a delivered event after rotation. Do not rotate
ARC-1's XSUAA binding or DCR signing key as part of this operation.
On SIGTERM/SIGINT, ARC-1 allows up to five seconds to drain requests and flush audit sinks before exiting. A timeout is logged and exits with status 1; SIGKILL cannot flush pending records.
Deployment and scaling by identity mode¶
| Mode | Instances | Upgrade strategy |
|---|---|---|
| Single target | One or more after testing stateful operations and load | Rolling can be used when release notes allow it |
| Multi-target, PP only | One or more after load testing | Rolling can be used when old/new versions are compatible |
| Multi-target with any Basic destination | Exactly one | Non-rolling stop/deploy/start with downtime |
| Mixed multi-target PP + Basic | Exactly one | Basic restriction governs the whole process |
For PP-only scaling, every process has its own immutable destination snapshot, per-user/IP rate buckets, and SAP semaphore. Restart and verify every process after target changes. Maximum SAP pressure is approximately:
Include other ARC-1 deployments that reach the same SAP system when sizing against Basis dialog work processes. Sticky sessions do not turn process-local state into shared coordination.
Data-preview RAM sizing¶
Data-preview memory admission is independently process-local. Each process admits at most
ARC1_MAX_CONCURRENT_DATA_RESULTS data-result calls and gives each complete tool call a cumulative
ARC1_MAX_DATAPREVIEW_RESPONSE_BYTES successful-body allowance. Calculate the raw admission
envelope E in MiB as:
At the defaults, E = 2 MiB × 2 = 4 MiB per process. With N instances, the fleet can admit
N × E, but every instance still needs enough RAM for its own E; horizontal scaling does not
protect one instance from an oversized result. This product is not a heap bound. The issue #737
full parse/result harness
measured about 19 times the combined raw XML bytes in incremental peak RSS before the fix, and XML
shape, string widths, transport, and allocator behavior can change that ratio.
For a new limit combination that has not yet been benchmarked, use this conservative planning estimate:
Then choose the next available CF memory tier above the estimate. The 32× multiplier rounds
well above the measured ~19× amplification; the 256 MiB reserve covers the server baseline,
native/HTTP buffers, caches, non-data requests, GC movement, and platform variance. This is a
starting allocation, not a guarantee. Do not use it to justify a smaller instance without a
representative concurrent peak-RSS test through the deployed direct or BTP/Cloud Connector route.
| Response allowance per tool call | Concurrent data results | Raw envelope E |
Planning estimate | Recommended starting CF RAM |
|---|---|---|---|---|
2 MiB (2097152) |
2 | 4 MiB | 384 MiB | 512M (shipped default) |
4 MiB (4194304) |
1 | 4 MiB | 384 MiB | 512M |
| 2 MiB | 4 | 8 MiB | 512 MiB | 1G |
| 4 MiB | 2 | 8 MiB | 512 MiB | 1G |
8 MiB (8388608) |
1 | 8 MiB | 512 MiB | 1G |
| 4 MiB | 4 | 16 MiB | 768 MiB | 1G |
| 8 MiB | 2 | 16 MiB | 768 MiB | 1G |
16 MiB (16777216) |
1 | 16 MiB | 768 MiB | 1G |
| 8 MiB | 4 | 32 MiB | 1,280 MiB | 2G |
| 16 MiB | 2 | 32 MiB | 1,280 MiB | 2G |
| 16 MiB | 4 | 64 MiB | 2,304 MiB | 4G |
Choose the pair for the workload rather than raising both automatically:
- For a batch/file consumer that needs a larger single result, raise
ARC1_MAX_DATAPREVIEW_RESPONSE_BYTESand normally lower concurrency to1first. - For more interactive users whose results stay small, keep the 2 MiB allowance and raise
ARC1_MAX_CONCURRENT_DATA_RESULTS;4should be the first load-tested step. - If both result size and throughput must grow, raise CF RAM from the table first, deploy, and run the maximum-size requests concurrently. Keep at least 20% observed RSS headroom under the CF limit; step up another tier if the test crosses 80%.
ARC1_MAX_CONCURRENTis the separate SAP HTTP-request limit. Raising it can add other in-flight response and request memory that this table does not model; do not use it as a substitute for the data-result limit, and continue to size it against SAP dialog work processes.
The shipped MTA sets OPTIMIZE_MEMORY=true and starts through a small fail-closed launcher. The
launcher validates the buildpack-provided MEMORY_AVAILABLE, assigns old-space 75% of it, and
then execs Node so CF termination signals reach ARC-1 directly: 384 MiB at the shipped 512 MiB
allocation, 768 MiB at 1 GiB, 1,536 MiB at 2 GiB, and 3,072 MiB at 4 GiB. See the official
Node buildpack guidance and
bin/release policy.
Memory overrides therefore remain in sync automatically. The Runtime memory envelope log reports
the total V8 heap limit, which includes more than old space; for example, the 384 MiB old-space
setting appears as approximately 432 MiB total V8 heap on the validated runtime.
Put the RAM and limit changes together in the durable customer .mtaext:
modules:
- name: arc1-mcp-server
parameters:
memory: 1G
properties:
ARC1_MAX_DATAPREVIEW_RESPONSE_BYTES: "4194304"
ARC1_MAX_CONCURRENT_DATA_RESULTS: "2"
Build and deploy the MTA rather than relying on a temporary cf scale; Cloud Foundry's
cf scale -m changes
the live per-instance memory limit, but the next MTA deployment reapplies the descriptor. After
deployment, confirm the Runtime memory envelope startup log shows the expected CF memory and V8
heap limit and the Data-result safety envelope log shows the intended raw envelope. Exercise the
widest approved row shape at full configured data concurrency, inspect cf app/platform memory,
and keep the larger tier until sustained evidence justifies reducing it.
Large MCP request bodies¶
For large source writes, set ARC1_MAX_HTTP_REQUEST_BYTES in .mtaext properties:
(100 KiB default, 16 MiB maximum) and align proxy limits. Follow the
request admission rules, including
proxy body/read timeouts. Before raising the limit in a small CF app, measure peak
RSS with concurrent large writes; admission is not a live-memory bound.
Data-preview response admission is separate.
Non-rolling update for shared Basic¶
Use a maintenance window. Do not pass a rolling strategy and do not use blue-green deployment:
# CF Space Developer, from the reviewed source checkout
cf stop arc1-mcp-server
npm run btp:build
npm run btp:deploy-ext
cf scale arc1-mcp-server -i 1
cf start arc1-mcp-server
cf app arc1-mcp-server
The normal MTA deploy may already start the application; the explicit start is harmless. The final
cf app output must show exactly one desired/running instance before users reconnect. Roll back by
stopping the app, deploying the previous reviewed MTAR with the same .mtaext and DCR secret, and
again verifying exactly one process.
enable-parallel-deployments: true in mta.yaml lets the MTA deployer schedule independent MTA
operations. It does not authorize two ARC-1 application processes and does not make rolling Basic
deployment safe.
Monitoring and incident evidence¶
Use request IDs to correlate MCP responses, ARC-1 audit events, Connectivity/Cloud Connector logs, and SAP logs. Keep log access restricted: even with central redaction, logs contain identities, target IDs, paths, statuses, timing, and topology evidence.
Useful read-only checks:
cf app arc1-mcp-server
cf services
cf env arc1-mcp-server # sensitive: inspect locally, never paste unredacted
cf logs arc1-mcp-server --recent
curl -fsS "https://<route>/health" | jq .
/health confirms that the process is up. In multi-target mode, HTTP 200 can coexist with zero
active targets or quarantined configuration. It does not prove Destination Service, PP, SAP login,
SAP authorization, data/SQL policy, or a usable tool catalog.
For multi-target acceptance, call SAPTargets as an Admin, review exclusions and registry revision,
then perform the same safe read through each endpoint style with a read-only pilot user: ordinary
Viewer for standard access, or an exact-target collection for filtered access. A plain Viewer has
no execution grants in filtered mode; test that denial separately. SAPRead SYSTEM alone
does not prove which SAP user processed the request. Follow
Verify the backend identity: expect
the human SAP user for PP or the approved technical user for shared Basic, and correlate the live
request with SAP-side evidence. The ARC-1 audit record must identify the human XSUAA caller.
Pre-customer acceptance¶
Record evidence rather than only checking configuration screens.
- [ ] The deployment mode and SAP identity model are written down.
- [ ] The reviewed
.mtaext, deployed ARC-1 version, route, CF org/space, and rollback MTAR are recorded. - [ ] The built MTAR was inspected and contains no
.env, service key, private key, certificate, or local operator file. - [ ] XSUAA, Destination, and Connectivity bindings point to the intended subaccount and space.
- [ ] All eight space-specific role collections exist and contain current roles; All Targets stays unassigned unless approved.
- [ ] Viewer, Data Viewer, Viewer + SQL, Admin, and no-role behavior match the expected tool surface. In filtered mode, pair capability tests with explicit target grants and separately test no-grant readers, denied targets and Admin without execution grants.
- [ ] After role changes, new application sign-in and catalog reload show the expected access; refresh alone is not treated as revocation. Follow the role-change procedure.
- [ ] PP maps to the intended SAP human in each target; wrong/unmapped and SAP-unauthorized users fail conclusively and can retry after repair.
- [ ] Cloud Connector exposes only the required paths and uses verified backend HTTPS.
- [ ] Multi-target Admin
SAPTargetsshows no unexpected quarantine, duplicate, shadow, or policy narrowing. - [ ] Pinned, aggregate, unknown-target, lowercase-route, bare
/mcp, and absent/targetsbehavior match the selected topology. - [ ] Named data preview and SQL work only where both instance and destination allow them.
- [ ] Aggregate/Basic routes expose no writes; pinned PP writes satisfy the write guide. Transport/Git management, SAP-backed formatter/settings actions, plugins, UI and hyperfocused mode remain unavailable. Permitted lint/transport reads match the reviewed action surface.
- [ ] ATC and ABAP Unit workload access is deliberately retained or denied; neither is run as a routine deployment smoke test.
- [ ] Shared Basic, if enabled, uses a least-privilege non-
SAP_ALLuser, monitored lockout/expiry, one CF process, and a rehearsed non-rolling update. - [ ] PP-only scale testing includes total process concurrency and consistent registry revisions.
- [ ] VS Code/GitHub Copilot, Cursor, and any customer-required MCP client completed OAuth, reconnect, catalog refresh, and one safe call.
- [ ] Logs/audit, backup, incident, secret-rotation, destination-change, and rollback owners accepted the handover.
Troubleshooting order¶
Work from the outer layer inward:
- Process and route:
cf app,/health, route, TLS, security headers. - MCP OAuth: protected-resource metadata, XSUAA token, role collection, fresh login.
- Registry: Admin
SAPTargets, destination marker/fields, duplicates, shadows, revision. - Destination/Connectivity: binding, lookup, Cloud Connector location and resource exposure.
- SAP authentication: certificate generated, STRUST, trusted proxy, CERTRULE/SU01 or Basic credential.
- SAP authorization: propagated/technical user has only required ADT permissions (for the startup user, see Startup user authorizations).
- ARC-1 policy: instance ceiling, destination data/SQL narrowing, user scope, deny actions.
Do not “fix” a downstream failure by widening an upstream boundary. For example, a SAP 403 after
successful PP login is an SAP-role problem, not a reason to expose / in Cloud Connector or grant
ARC-1 Admin.