Multi-Target Administration¶
Experimental v1
Multi-target mode is default-off and mutation-free. Treat it as a shared read gateway, not as 256 isolated ARC-1 instances.
This page is the operator reference for security boundaries, registry behavior, diagnostics, capacity, and incident handling. Follow BTP Cloud Foundry Deployment for deployment and Multi-System Setup for the destination/endpoint reference. For restricted users, choose target access setup before assigning roles. Common BTP configuration ownership, XSUAA collection lifecycle, DCR secrets, upgrades, scaling, rollback, logging, and customer handover live in BTP Administration.
This page distinguishes standard access (configuration value standard) from target-filtered
access (xsuaa-attribute, also called enforced mode). Standard access is supported, not deprecated:
choose it when all readers may see/try the shared inventory. Filtering is optional and uses IAM
assignments, not a scan of SAP accounts. See when to use it.
Check availability and readiness
before planning activation.
Operating model¶
Responsibility is intentionally split across administrators:
| Owner | Controls | Security effect |
|---|---|---|
| ARC-1 deployment owner | ARC-1 application environment, usually deployed through MTA | Enables the mode and sets the application-wide maximum for data and SQL. |
| BTP destination administrator | One subaccount destination per SAP connection | Defines the real SID/client, optional public route alias, connection, label, and narrower data/SQL opt-ins. |
| Identity administrator | XSUAA roles and collections | Grants global capabilities; with opt-in target authorization, also assigns exact target cohorts or explicit all-target access. |
| Cloud Connector administrator | Virtual mappings, principal mode, trust, and exposed paths | Carries the selected destination securely to the intended SAP backend. |
| SAP/Basis administrator | PP mapping or shared technical user, plus SAP authorizations | Determines whether the selected per-user or shared SAP identity can access a client and operation. |
A request succeeds only when all applicable layers permit it:
multi-target v1 ceiling
∩ ARC-1 instance ceiling
∩ selected destination policy
∩ XSUAA user scope
∩ target grant (only when xsuaa-attribute enforcement is enabled)
∩ selected SAP identity authorization
No layer can widen an earlier one. MCPAdmin cannot bypass SAP authorization or unlock mutations on
multi-target routes. PrincipalPropagation targets are per-user; explicitly enabled
BasicAuthentication targets are shared and use the same SAP technical user for every scoped
XSUAA caller.
OAuth grant behavior¶
Multi-target protected-resource metadata advertises read, data, sql, and admin, and the
initial 401 does not force one fixed scope. General MCP clients request that mutation-free set;
XSUAA intersects it with the authenticated user's assigned role collections, and ARC-1 filters the
tool/action surface from the resulting token. A validated token without global read still receives
403 before route membership is resolved.
This makes role changes visible after logout/reconnect in clients that do not support reliable MCP scope step-up. It also means a trusted Admin receives all assigned mutation-free scopes at initial login. Treat the token accordingly and keep its lifetime short. This model must be redesigned—not merely expanded—before any multi-target write, transport, or Git scope is introduced.
A pinned route reduces accidental target switching, but it is not by itself an access-control rule. With standard access, a global read user can try every accepted pinned route. Enforced mode checks a target grant first. The aggregate route introduces an additional wrong-target risk: a model can select a different authorized system and read data or run SQL there. Keep data/SQL off unless approved, use distinct factual descriptions, and separate lookalike systems when that risk is unacceptable.
When separate instances are safer¶
Use one ARC-1 instance and a separate MCP connection per target when you need:
- writes, activation, transport mutation, or Git mutation;
- target-specific visibility without enabling target authorization, or different capabilities per target for the same user;
- different XSUAA tenants, subaccounts, or identity providers;
- hard performance, maintenance, or failure isolation;
- independent production and non-production security boundaries; or
- a security boundary stronger than a shared process with per-request target validation.
Multi-target v1 reduces application sprawl; it does not create independent security or capacity domains inside one process.
SQL and client isolation¶
Target grants select an authorized destination and SAP logon client; they are not a SQL
row/client-isolation policy. Freestyle ABAP SQL can override implicit client handling where the
backend permits it (USING CLIENT or release-dependent explicit-client syntax), and client-independent
tables have no per-client partition. SAP itself advises against explicit client access in ordinary
business applications; see SAP's client-handling guideline.
Keep freestyle SQL off if the customer requires every returned row to belong to the selected client. Use a separately reviewed backend service with explicit data authorization for that requirement; do not treat a target grant, PP identity, or a keyword blacklist as proof of row isolation. This limitation predates target grants. The feature does not introduce a SQL parser/row-security engine.
Target authorization lifecycle¶
Activation and rollback¶
To enable target authorization, follow the static-cohort setup:
prepare roles unassigned, activate and verify ARC1_MULTI_TARGET_AUTHORIZATION=xsuaa-attribute,
then assign restricted users. Target roles include global read, so assigning them to a reachable
standard-access instance would expose all its targets. Existing deployments keep standard access
when the property is absent; explicitly setting standard has the same effect. Only trusted
deployment operators may change this policy. Keep the chosen value in the protected landscape
extension, not only a temporary cf set-env override.
| Change | Operator action |
|---|---|
| Assign/remove a target role or collection | Follow role changes and revocation: new application sign-in, verify the resulting access, then reload MCP tools. Refresh alone can retain removed grants. No destination restart is required. |
| Login/catalog still reflects old access | Use the session-recovery procedure. The Refresh access link is only on eligible invalid_scope pages; successful login with stale target grants may show no such link. |
| Rename a public target alias/client ID | Coordinate the destination change, exact role values, all-process restart and fresh client login. Old IDs do not become aliases automatically. |
| Repoint a destination under the same public ID | Existing grants still match. Require the IAM/data owner's review before routing those grants to a different backend. |
| Activate enforcement | Deploy the reviewed multi-only extension, verify the effective mode on every process and run positive/negative user acceptance. |
| Disable/roll back enforcement | Obtain the security owner's approval, then set ARC1_MULTI_TARGET_AUTHORIZATION: standard explicitly in the owning protected .mtaext, deploy, and verify the actual CF environment and logged mode on every serving process. This security downgrade restores broader all-reader access; verify that population and never use it as automatic error recovery. |
An actually unset runtime setting also selects standard, but deleting the line from an MTA
extension does not reliably unset an already-deployed CF value. Keep the explicit rollback value
in the owning extension; see configuration persistence.
Before any downgrade, review the entire reader population, including users who gained read from
the new target roles. Keep the route closed until every remaining reader is approved for all
configured targets. Removing a collection alone does not invalidate already-issued tokens or stale
refresh/SSO sessions. Do not reopen based only on an IAM assignment diff or an elapsed hour;
verify the effective access under the customer's revocation procedure. Prefer fixing forward
with enforcement enabled rather than widening access to restore service.
Role changes and revocation¶
- Have IAM verify the intended application's assignments and IdP origin, including all collections contributing targets/capabilities. Use a dedicated test cohort when changing values for a pilot.
- Start the MCP client's sign-out/re-authentication flow, not only reconnect or token refresh. A refresh can issue a new token with old permissions.
- If ARC-1 displays an eligible
invalid_scopefailure page, use Role assigned? Refresh access and then start sign-in again. If login succeeds but access is stale, there may be no such link: try a fresh private browser window, or ask the deployment owner for the application's configured XSUAA logout link. See session recovery. Confirm the email and IdP origin. Opening ARC-1's/oauth/logged-outdirectly only displays a confirmation page; it does not clear the XSUAA session. - Verify the new session's actual permitted/denied calls and caller-specific grant summary, then reload the client's tools. Do not infer updated grants merely from a new token expiry or login form. Keep old-token/refresh observations separate from the newly authenticated session's result.
An already-issued token retains its old grants until expiry; changing a role, signing out, or restarting ARC-1 does not revoke every outstanding token. Live tests also showed refresh and reused SSO issuing new tokens with removed grants. Immediate revocation is not provided by this feature. Missing/invalid grants fail closed, but stale valid grants remain valid until the relevant access ends.
The shipped mta.yaml and xs-security.json set token-validity: 3600 (1 hour) and
refresh-token-validity: 2592000 (30 days). The latter is longer than SAP's documented default
of 604800 seconds (7 days); see XSUAA descriptor configuration.
These are configured token lifetimes, not a one-hour or 30-day revocation guarantee. The IAM
and deployment owners must review their effective settings, refresh/SSO behavior and acceptable
revocation window; shortening settings is a separate reviewed change, not a retroactive revocation.
For urgent containment, use the security owner's incident procedure (for example closing the ARC-1
route). Basis can restrict the mapped SAP user/authorizations for PP targets, but must verify the
effect on active SAP sessions; that does not remove ARC-1 inventory grants or apply to shared Basic users.
Instructions, tools/list, and catalogs are caller-specific. ARC-1 emits Cache-Control: private,
no-store for enforced MCP responses, including streaming output. Do not add shared proxy caching;
an MCP client can still retain its own tool catalog, so reconnect/reload it after identity or grant
changes. Server-side checks remain authoritative even if the client tries an old or hidden target.
Admin can see complete safe inventory without a target grant, but cannot execute on an ungranted target. Grant a specific cohort for operator test calls, or deliberately assign the separate All Targets collection. Functional permissions apply over the complete grant union; see the scope/target limitation.
Do not collect raw JWTs, complete grant arrays, IAS group lists or credentials in support tickets. Record the effective mode, application/IdP identity, request ID and safe decision/status counts. CLI platform login is not evidence that the application's user token has the expected grants.
Process and registry lifecycle¶
Startup contract¶
When ARC1_MULTI_TARGET_ENDPOINTS=true, startup validation requires:
SAP_TRANSPORT=http-streamableandSAP_XSUAA_AUTH=true;- BTP CF XSUAA, Destination, and Connectivity bindings rather than a service key;
ARC1_CACHE=none,ARC1_TOOL_MODE=standard, andARC1_UI=off;- no plugins, shared cookie source, or
SAP_PP_ALLOW_SHARED_COOKIESescape hatch; and - no direct
SAP_URL,SAP_USER, orSAP_PASSWORDconnection.
PrincipalPropagation runtimes always force strict per-user PP. BasicAuthentication runtimes are
accepted only when ARC1_MULTI_TARGET_ALLOW_BASIC_AUTH=true; the flag is false by default, and
Basic never becomes fallback for PP. SAP_PP_ENABLED and SAP_PP_STRICT control only an optional
single-target /mcp runtime; they do not change a discovered target's identity mode.
When Basic multi-target is enabled, keep exactly one CF app instance. Its credential-generation guard and passive authentication health are process-local. PP-only multi-target retains the existing scaling behavior.
The process may start with zero targets. This supports deploy first, create destinations second, then restart.
Optional single-target /mcp¶
This mixed topology requires standard access (standard). Enforced mode rejects independent single-target connection
settings before startup destination lookups or SAP probes. Use a separate application and XSUAA
identity with reviewed assignments when single-target access is also required. Also review other
apps sharing the current XSUAA identity; this process cannot restrict their endpoints.
An explicitly configured SAP_BTP_DESTINATION and optional SAP_BTP_PP_DESTINATION may keep one
single target at bare /mcp. Discovered targets are never assigned there and do not inherit the
single target's destination names or policy.
The single-target endpoint retains its normal configuration, including possible write/package behavior; the discovered pinned and aggregate routes remain mutation-free. Process-wide multi-target startup constraints—cache none, standard tools, UI/plugins/cookies/direct credentials off—still affect the single-target runtime.
Use least privilege in side-by-side deployments
MCPAdmin implies all ARC-1 scopes. The token cannot write through multi-target routes, but it
may write, release transports, or operate Git through a write-enabled single-target /mcp. Do not
grant Admin merely for routine target discovery. Prefer a separate application if operators
need diagnostics while ordinary users need a writable single-target endpoint.
If a per-user/PP single-target destination is also discovered as a public target route, both
endpoints remain available and may have different effective policies. ARC-1 logs a warning because
that duplication is usually unintentional. A shared-Basic SAP connection cannot be exposed through
both bare /mcp and a multi-target route in v1; ARC-1 rejects that configuration at startup.
Copilot Studio's JSON-RPC compatibility traffic sent to /authorize always uses the mutation-free
aggregate server while multi-target mode is enabled. It does not select the side-by-side /mcp,
even when that single-target endpoint is configured and writable. Connect clients directly to
/mcp only when the single-target surface is intentional.
Discovery, conflicts, and the 256-target ceiling¶
ARC-1 reads one immutable snapshot of BTP subaccount destinations at startup. It also reads service-instance destination names only to detect same-name shadowing; instance destinations do not become targets.
A CF space is not a hard destination-inventory boundary. If two ARC-1 populations must not share subaccount destination visibility, isolate them in separate subaccounts or another deliberate platform boundary. Same-name instance destinations are quarantined rather than allowed to override a subaccount target through normal Destination Service lookup precedence.
Only destinations containing an arc1.* property enter detailed ARC-1 validation. A destination is
active only when arc1.enabled=true and all connection/identity fields pass validation.
Conflict handling is deterministic and fail closed:
- duplicate destination names quarantine every enabled claimant; disabled or marker-missing entries remain non-active;
- multiple enabled destinations claiming one public target ID quarantine every claimant;
- a subaccount candidate shadowed by a same-name instance destination is excluded; and
- with standard access, more than 256 enabled candidates activates none of them—ARC-1 never chooses a “first 256”.
Invalid enabled destinations count toward that standard-access ceiling. With xsuaa-attribute, the bound
is 256 total ARC-related candidates, including disabled, invalid and marker-missing entries;
case-insensitive arc1.* property detection prevents malformed capitalization evading the count.
Unrelated destinations do not count. Exceeding it makes the entire registry unavailable, with no
partial routable snapshot. Destination ordering never selects a winner.
Enforced mode also bounds the complete serialized MCP ToolResult to 512 KiB, including the escaped text wrapper. A startup catalog that cannot fit makes the registry unavailable; output is never silently truncated. These are safety ceilings, not a promise that a 256-grant enterprise JWT fits every proxy or MCP client. Begin sizing at 50/100 exact grants and measure actual token/header and catalog sizes before expanding; live scale acceptance is still pending.
When separate systems reuse a real SID/client, set arc1.target_alias on at least one so their
public IDs differ—for example, preserve A4H/001 and add A4H-2025/001. You may alias both for
symmetry. Both descriptors retain real sid: "A4H" and client: "001". Duplicate detection uses
the public ID. An alias is model-visible routing metadata, not an authorization boundary; prefer an
alias that starts with the real SID and a factual Description.
Restart, drift detection, rotation, and CF instances¶
Creating, editing, disabling, or deleting a destination does not change a running snapshot. Use a normal restart so every CF app instance loads the new configuration:
No new MTAR or cf deploy is required for destination-only changes.
Before each SAP call, ARC-1 resolves the selected destination without a destination cache and
requires the Destination Service response to identify a subaccount owner. An instance-level owner
is rejected even when its safe configuration matches. ARC-1 then compares the safe connection,
public alias, and policy fingerprint with the startup snapshot. A mismatch returns
TARGET_CONFIG_CHANGED until restart. PP additionally validates the current user JWT with the
Connectivity service on every call. Failed PP or per-user SAP access is not cached, so mapping and
authorization repairs can be retried immediately.
Basic User/Password values are intentionally excluded from that fingerprint. ARC-1 loads them
inside a process-wide per-target gate, stores only a keyed generation digest, and uses one backend
authentication attempt for a new generation. A rejected generation stays blocked to protect the
SAP account; changing the destination credentials admits a new generation without restart. For
zero downtime, switch atomically to a second reviewed technical user and revoke the former user
only after safe reads succeed. A same-user password change can have a short outage window.
For PP-only scaled deployments, verify that every CF instance reports the same registry revision
through admin SAPTargets. To route an authenticated aggregate MCP request to one instance, use
X-CF-APP-INSTANCE: <app-guid>:<index> and compare revisions. Do not scale a Basic-enabled v1 app.
Health states¶
/health intentionally remains HTTP 200 to avoid a CF crash loop.
| Health component | Meaning |
|---|---|
multiTarget.status="ready" |
The registry snapshot is usable. Zero active targets and individually quarantined destinations are still valid snapshots. |
multiTarget.status="error" |
Discovery failed or the mode-specific candidate/result-size ceiling invalidated the entire registry. |
During registry-wide failure, /multi/mcp stays reachable so an admin can call SAPTargets.
With standard access, pinned routes return HTTP 503 and other aggregate tool calls return a structured
registry error. Enforced mode checks the caller's target grant first: an ungranted ID still returns
generic pinned HTTP 404 or aggregate TARGET_NOT_AVAILABLE; only a granted ID reaches the pinned
503 or aggregate MULTI_TARGET_REGISTRY_UNAVAILABLE result.
The admin catalog distinguishes ready, degraded, and error configuration states in more
detail than /health.
Destination policy operations¶
The complete field table and minimal/SQL examples are in Destination configuration. The operational rules are:
- the only supported v1 keys are
arc1.enabled,arc1.allow_data_preview,arc1.allow_free_sql, and optionalarc1.target_alias; arc1.target_aliaschanges only the public target/pinned route; realsap-sysidandsap-clientremain required for SAP and are visible to admins in diagnostics;- omitted data/SQL values are false and the two switches are independent;
- unknown
arc1.*keys and any write/package/transport/Git key quarantine an enabled destination; limitedByInstance: truemeans a target requested data or SQL above the current instance ceiling; source reads remain active;- changing any target field or policy requires a restart, except Basic
User/Passwordrotation; and - there is no
arc1.config_versionor full-write destination profile in v1.
Descriptions are returned to users and models. Treat them as untrusted labels: no prompts, instructions, credentials, secrets, token-bearing links, or sensitive notes.
Destination exports may contain connection or authentication material. Never commit, attach, paste, or screenshot an unredacted export. If an example must be shared, remove URLs, location IDs, credentials, tokens, certificates, and any nonessential topology details.
Basic shared-identity controls¶
BasicAuthentication is a compatibility option, not the recommended enterprise identity model. Enabling it separates responsibility deliberately: the deployment owner permits shared identity, the destination administrator controls the credential, XSUAA controls which humans may call ARC-1, and SAP authorizes only the technical user.
- Use a dedicated communication/technical user with the minimum ADT permissions required by the
exposed read actions. Never use
SAP_ALL.S_ADT_RESpermits URI prefixes, not activities; trace backend authorization checks separately even for read-like POST operations. See the SAP authorization guidance. - Do not assign developer-wide, transport, activation, or write authorizations merely because the user is technical. Multi-target v1 cannot use them, and they enlarge the impact of credential misuse outside ARC-1.
- Prefer a different technical user per client and security boundary. Do not share one credential across unrelated production and non-production systems.
- Configure password-expiry and account-lock monitoring in SAP according to the customer's policy. Alert on impending expiry, locked users, repeated failed logons, and unexpected use outside the reviewed ADT paths. ARC-1 audit records identify the human XSUAA caller; SAP records only the shared technical user.
- Use a separate Cloud Connector mapping with principal type None (
NONE_RESTRICTEDin the API), restricted ADT paths, and an internal HTTPS connection to SAP. An HTTP internal hop exposes the reusable Basic password; ARC-1 cannot verify the mapping protocol. - Confirm
/sap/bc/adtaccepts HTTP Basic for the technical user. ARC-1 suppresses SAML and rejects a 2xx HTML/SSO login page; it cannot make an SSO-only ICF logon procedure accept Basic. - Restrict and audit destination-administrator access as credential-administrator access.
- Keep data/SQL off unless approved; SAP attributes those calls to the technical user.
- Keep exactly one CF app instance and deploy it non-rolling. A rolling/blue-green replacement can temporarily create a second independent guard even when the desired count is one. A Basic target serializes request-time destination lookup, credential-generation validation, canary/feature handling, and dispatch through one bounded process-local gate.
- For zero-downtime rotation, prepare a second least-privileged technical user, atomically update
both destination
UserandPassword, perform safe reads through the pinned and aggregate routes, and only then revoke the former user. For a same-user password change, accept a possible consistency/outage window: SAP normally cannot keep both passwords valid. Verify rotation with successful safe reads and absence of a shared-auth exception; aggregate healthy counts alone do not prove that a new credential generation was used. Do not change another destination field in the same rotation unless you also plan a restart.
If per-user SAP attribution, target-specific SAP authorization, or horizontal scaling is required, use Principal Propagation or separate ARC-1 applications.
SAPTargets operator surface¶
SAPTargets is an authenticated MCP tool available only on /multi/mcp. There is no /targets
HTTP endpoint and no public target inventory. It goes through normal scope and deny-action checks,
request IDs, audit events, and the per-user MCP limiter when ARC1_RATE_LIMIT is configured.
Reader view¶
With standard access, readers see the tool only when more than one target is active. With no arguments it returns accepted public IDs, descriptions, and the effective SAP identity mode:
[
{ "target": "A4H/100", "description": "A4H development client 100", "identity": "per-user" },
{ "target": "NPL/001", "description": "Read-only NPL client 001", "identity": "shared" }
]
Optional query is a case-insensitive filter over target ID and description. The reader result does
not expose destination names, URLs, policy, rejected entries, credentials, or runtime
authentication health. per-user means Principal Propagation; shared means every caller uses the
destination's technical SAP user. A listed target is configured; it is not proof that the current
user can access SAP.
Admin user¶
Admins see SAPTargets at zero, one, or many active targets and during registry failure. Their
response wraps the public target list and adds secret-projected registry state.
With standard access, without query, diagnostics contain a bounded page of non-active ARC-related destinations and
their exclusion reasons. With query, diagnostics also include matching active targets and can
match target ID, active-target description, destination name, status, code, or safe message.
admin.sharedAuthentication contains passive counts for not_checked, checking, healthy,
configuration_invalid, authentication_failed, authorization_failed, and
temporarily_unavailable. With standard access, at most 8 non-normal target rows are returned in exceptions, with
explicit total/returned/truncation metadata; narrow query to the target ID when that list is
truncated. Reading SAPTargets never performs a destination lookup, SAP login, canary, or feature
probe; this is only the last process-local state observed during a real request.
When an active target uses an alias, a matching admin diagnostic correlates its public target
with the real sid and client, and reports the validated value as arcConfig.targetAlias.
Readers still receive only target, description, and identity.
{
"targets": [
{
"target": "NPL/001",
"description": "Read-only NPL client 001",
"identity": "shared"
}
],
"admin": {
"state": "degraded",
"source": "btp-subaccount",
"loadedAt": "<timestamp>",
"revision": "<sha256-hex>",
"counts": {
"scanned": 2,
"unrelated": 0,
"arcAdjacent": 0,
"arcRelated": 2,
"enabled": 2,
"active": 1,
"disabled": 0,
"ignored": 0,
"quarantined": 1
},
"sharedAuthentication": {
"targets": 1,
"statusCounts": { "healthy": 1 }
},
"diagnosticMode": "exceptions",
"diagnosticOffset": 0,
"diagnosticTotal": 1,
"diagnosticReturned": 1,
"diagnosticsTruncated": false,
"destinations": [
{
"destinationName": "ARC1_INVALID_PP",
"status": "quarantined",
"code": "INVALID_SYSID",
"message": "sap-sysid must match three uppercase alphanumeric characters and start with a letter.",
"type": "HTTP",
"proxyType": "OnPremise",
"client": "100",
"hasCloudConnectorLocationId": false,
"arcConfig": { "enabled": true },
"warnings": []
}
]
}
}
The standard-access diagnostics above are sorted and paged at 50 rows. When diagnosticNextOffset is present, call the tool
again with the same query and offset set to that value. offset is admin-only, accepts integers
from 0 through 1,000,000, and makes every matching destination reachable without one unbounded
result. query is optional and limited to 160 characters; extra arguments are rejected. Raw query
text is not written to the audit event.
arcAdjacent counts subaccount destinations that contain sap-sysid or sap-client but no
arc1.* marker. Their names are not returned. The count helps identify a likely missing
arc1.enabled=true without exposing unrelated inventory.
Admin output never contains:
- destination URLs or raw Destination Service objects;
- users, passwords, client secrets, tokens, SAML assertions, or authorization headers;
- destination query/header properties or certificates;
- raw Cloud Connector location IDs; or
- per-user SAP/PP failures or inferred availability.
hasCloudConnectorLocationId is a boolean only, and the revision is derived from safe normalized
configuration. The admin response is still operator-sensitive: it exposes internal destination
names, topology labels, normalized policy, and failure reasons to the MCP client/model. Use it only
in trusted operator sessions and redact it before pasting into issues, pull requests, chats, or
support tickets.
Enforced catalog differences¶
Only opt-in target authorization changes this contract; standard-access paging and tool visibility stay unchanged.
Display compatibility note (both modes): destination labels remove Unicode control/format
characters before display. Ordinary labels are unchanged. A previously accepted label containing
invisible format characters can therefore change its normalized description, target fingerprint
and published registry.revision on upgrade. This is intentional display hardening, not an IAM
grant or routing-policy change; revision strings are snapshot identifiers, not stable target IDs.
| Audience | SAPTargets in enforced mode |
|---|---|
| Reader | Available only with more than one granted active target on the aggregate route. Returns only those targets' IDs, descriptions and identity labels. No hidden counts or rejected inventory. |
| Admin | Available at zero/one/many grants. All active targets with a granted boolean, plus all safe active/non-active diagnostics and an admin.authorization summary (mode, grantMode, status, and exact-grant count where applicable). No raw grant list. |
At zero granted active targets, a reader receives tools: [] and only a caller-specific no-target
explanation. At one, SAP tool schemas contain the one exact target, still required on each call,
but no SAPTargets. Calling the unlisted catalog directly returns UNKNOWN_TOOL; it cannot reveal
whether another user has more targets. Existing deny-actions also apply, including to Admin.
Only optional query is accepted (at most 160 characters); offset and other arguments are
rejected. Without a query the Admin gets the complete bounded inventory, not an exceptions page.
A query filters displayed rows, not registry totals or aggregate Basic health counts. Every matching
Basic exception is included, without the standard-access eight-row cap. The same passive/no-probe rule applies.
The total-candidate and serialized-result bounds
make completeness possible. Oversized snapshots are unavailable rather than partially active.
When discovery stopped at the limit, countsComplete:false and arcRelatedAtLeast explicitly mark
the incomplete count; ordinary counts are omitted rather than invented. Invalid diagnostic fields
are sanitized/omitted for display without making an invalid destination valid.
Status, warning, and failure codes¶
| Code | Status / operator action |
|---|---|
ACTIVE |
Target is routed. limitedByInstance may still show that requested data/SQL was narrowed. |
MISSING_DESCRIPTION |
Nonfatal warning on an active target; add a useful factual label. |
ARC1_ENABLED_MISSING |
ARC-related destination has no marker; add arc1.enabled=true if intended. |
ARC1_DISABLED |
Target is explicitly disabled; set true and restart if it should be active. |
ARC1_ENABLED_INVALID |
Use a boolean true or false. |
MISSING_NAME / INVALID_NAME |
Add or repair the destination name. |
MISSING_URL / INVALID_URL |
Add a valid HTTP/HTTPS URL. |
MISSING_SYSID / INVALID_SYSID |
Add/fix sap-sysid using the exact three-character format. |
INVALID_TARGET_ALIAS |
Remove the alias or use 3–32 uppercase letters/digits with internal hyphens, starting with an uppercase letter and without the client suffix. |
MISSING_CLIENT / INVALID_CLIENT |
Add/fix the three-digit sap-client. |
UNSUPPORTED_TYPE |
Use an HTTP destination. |
UNSUPPORTED_PROXY |
V1 requires OnPremise. |
UNSUPPORTED_AUTH |
Use PrincipalPropagation, or explicitly permitted BasicAuthentication. |
BASIC_AUTH_DISABLED |
The Basic destination is quarantined because ARC1_MULTI_TARGET_ALLOW_BASIC_AUTH is false/unset. Enable it only after accepting the shared-identity boundary. |
BASIC_PREEMPTIVE_DISABLED |
Remove Preemptive=false or set it to true, then restart. |
INVALID_LANGUAGE |
Remove or correct sap-language. |
UNKNOWN_ARC1_PROPERTY |
Remove or correct the unsupported ARC-1 property. |
INVALID_POLICY |
Set the data/SQL property to true or false. |
UNSUPPORTED_V1_WRITE_CONFIG |
Remove write-related properties; writes are unavailable. |
DUPLICATE_TARGET |
Give every enabled destination a unique public target ID. Systems sharing a real SID/client need an alias on one or both destinations; every duplicate claimant is quarantined. |
DUPLICATE_BASIC_CONNECTION |
Keep exactly one enabled Basic destination for each physical URL/client/Cloud Connector location. Aliases cannot duplicate a shared Basic backend; every claimant is quarantined to preserve the lockout guard. |
DUPLICATE_DESTINATION_NAME |
Remove duplicate inputs; every enabled claimant is quarantined and all claimants remain non-routable. |
SHADOWED_BY_INSTANCE |
Remove/rename the same-name instance destination or subaccount candidate. |
TARGET_LIMIT_EXCEEDED |
Reduce enabled candidates (standard access) or all ARC-related candidates (enforced) to 256 or fewer and restart; none are active while over limit. |
CATALOG_SIZE_LIMIT_EXCEEDED |
Enforced only: the full safe catalog cannot fit 512 KiB. Reduce/review inventory and restart; no partial result or partial snapshot is accepted. |
REGISTRY_DISCOVERY_ERROR |
Check Destination binding/token/network health, then restart. |
LIMITED_BY_INSTANCE is not a reason code. An active entry keeps code: "ACTIVE" and sets
limitedByInstance: true when its requested policy exceeds the instance ceiling.
User access failures and retries¶
ARC-1 reports the proven failure stage without exposing raw SAP responses:
| Error | Meaning and response |
|---|---|
| Generic target unavailable/denied | Enforced mode intentionally does not distinguish an unknown ID from an ungranted ID. Use a trusted Admin session and the request ID to diagnose; never probe other IDs as a workaround. |
TARGET_GRANT_MISSING / TARGET_GRANT_MALFORMED / TARGET_GRANT_LIMIT_EXCEEDED |
Safe Admin/audit decision: check the correct application's role source/values, missing versus Unrestricted attribute, exact ID format and the 256 unique-grant bound. Fresh sign-in after IAM repair; no fallback to standard. |
TARGET_NOT_GRANTED |
Operator audit only: the user's valid grant set does not include the requested target. The caller still gets a generic unavailable/denied response; this code does not prove the target exists. Distinguish this ARC-1 decision from downstream PP/SAP failures. |
BASIC_CREDENTIALS_MISSING |
The authoritative request-time Find result has no usable User/Password. Repair the destination and retry without restart. |
BASIC_CREDENTIALS_INVALID |
The Basic username contains : or surrounding whitespace. Correct the destination and retry without restart. |
DESTINATION_AUTH_SETUP_FAILED |
Destination Find or Basic request-client preparation failed safely before ADT. Check the request ID and Destination/Connectivity health; retry only when transient or after repair. |
PP_SETUP_FAILED |
Destination/Connectivity lookup or token exchange failed before ADT dispatch. Repair PP/Cloud Connector and retry immediately. |
CLOUD_CONNECTOR_ACCESS_DENIED |
BTP Connectivity returned its specific exposure denial before SAP handled the ADT request. PP targets must match the reviewed HTTPS/X.509 PP mapping. Basic targets need a separate reviewed principal-type-None (NONE_RESTRICTED) OnPremise mapping and do not use the PP identity certificate. Allow the required ADT paths, then retry. |
SAP_AUTHENTICATION_FAILED |
PP: SAP returned login/401 behavior and mapping/login must be repaired. Basic: SAP rejected the shared credential generation. ARC-1 will not retry that generation for 15 minutes, but an unchanged bad credential can be attempted once again after expiry or process restart. Update destination credentials promptly instead of treating the block as permanent. |
SAP_AUTHORIZATION_DENIED |
SAP returned a structured authorization refusal. PP: repair the propagated user's role and retry. Basic canary: repair the technical user's least-privilege ADT role, then restart, wait 15 minutes for the temporary block, or rotate credentials. |
SAP_SERVICE_INACTIVE |
The target ICF/ADT service is inactive or unreachable in that form, rather than merely a user-role issue. |
SAP_REQUEST_FAILED |
A post-resolution network error or SAP 5xx prevented the request without proving an auth failure. Check Cloud Connector/SAP health and retry once. |
SAP_TARGET_BUSY |
The Basic target's bounded serialization queue is full or the wait timed out. Retry after the active request completes; split/load-isolate the target if persistent. |
SAP_TARGET_TEMPORARILY_UNAVAILABLE |
The Basic canary had a network, timeout, 429, SAP 5xx, or unrecognized non-login 2xx response. The credential generation is not poisoned; check SAP/intermediary health, then retry. |
TARGET_POLICY_DENIED |
Data/SQL is not enabled at every ARC-1 policy layer. |
TARGET_CONFIG_CHANGED |
A non-secret destination field no longer matches the startup snapshot. Review it and restart. Basic User/Password rotation alone does not cause this error. |
For empty reader tool lists, inspect target_resolution_failed audit events with
tool: "aggregate-mcp" during initialize or tools/list (including the Copilot alias).
The safe errorCode distinguishes missing, malformed and over-limit grants without logging raw
attribute values. An unrelated valid grant naming an inactive/unknown target is not malformed.
One invalid value rejects the whole grant set, even alongside *; a trailing non-breaking
space is invalid, not silently trimmed. Re-enter exact ASCII IDs in IAM and follow the
role-change procedure before retrying. Admin catalog summaries
describe the calling Admin's grants, not another user's token.
PP setup success is not proof of SAP login. PP/per-user access failures are deliberately not cached: after Basis fixes mapping or authorization, the user can say “try again now” in the same conversation. Basic failures differ deliberately: the rejected credential generation remains blocked for 15 minutes, including a bounded set of recently replaced generations. A changed credential can proceed immediately; process restart also clears the block. An unchanged bad credential may be attempted once again after expiry, so SAP account-lock monitoring remains necessary. A changed XSUAA role requires a new OAuth token/sign-in.
HTTP middleware enforces XSUAA before tool dispatch. Audit events distinguish downstream target resolution, effective identity mode, PP exchange where applicable, Basic credential-generation state, Cloud Connector exposure denial, SAP authentication, SAP authorization, and execution. Raw authentication bodies and secrets are suppressed. SAP sees only the technical user for Basic targets, so human attribution requires the ARC-1 request/audit record. Whether SAP itself logs each login attempt depends on SAP security configuration.
Shared capacity and rate limits¶
Every target and optional single-target route shares one ARC1_MAX_CONCURRENT semaphore per CF app
instance. The default 10 means ten concurrent SAP requests across the whole process—not ten per
target. Destination count alone does not justify a higher value; expected active users and SAP
dialog work-process capacity do. A busy target can temporarily occupy all slots.
For PP-only deployments, each additional CF process creates another semaphore, so horizontal scaling multiplies the possible load on a target. Basic-enabled multi-target v1 must remain at one CF process because its credential-generation protection is process-local. Size the fleet against the most constrained SAP target and include every ARC-1 process from other deployments that can reach it. If substantially different SAP capacities require different caps, split those targets into separate ARC-1 deployments.
The authoritative formula and shared-beta rate starting points are in
Multi-target shared beta (BTP CF). Do not derive
ARC1_MAX_CONCURRENT from user or destination count. ARC1_RATE_LIMIT defaults to off;
multi-target logs a warning when it is zero, so start with the documented positive per-user limit and
tune from audit and latency evidence.
ATC and ABAP Unit are available to the existing read role in multi-target mode for compatibility
with single-target authorization. They are mutation-free at ARC-1's repository boundary but execute
SAP workloads (ABAP Unit currently includes all risk levels and short, medium, and long durations).
Review this with Basis before customer rollout. Use positive rate limits and an SAP-sized concurrency
cap, or disable one or both with
SAP_DENY_ACTIONS=SAPDiagnose.atc,SAPDiagnose.unittest. On a shared Basic target, the workload and
SAP-native attribution belong to the destination technical user even though ARC-1 audits the human
caller.
Operational checklist¶
- [ ] The feature is explicitly enabled and all multi-target routes remain mutation-free.
- [ ] XSUAA, Destination, and Connectivity bindings are healthy.
- [ ] Every target has an intentional identity: strict Principal Propagation, or explicitly enabled Basic with no fallback between modes.
- [ ] PP destinations match an HTTPS/
X509_RESTRICTEDmapping and CERTRULE setup; Basic destinations match a separate principal-type-None mapping with internal HTTPS and a Basic-capable ADT ICF logon procedure. All required ADT paths are allowed. - [ ] Basic uses a least-privileged technical user (not
SAP_ALL), strong reviewed credentials, password-expiry/account-lock monitoring, audited destination administration, and exactly one non-rolling CF instance. - [ ] Every target has a valid real SID, client, factual description,
arc1.enabled=true, and a unique valid route alias when its SID/client is reused. - [ ] Data/SQL is approved and enabled only where required at both instance and target layers.
- [ ] No target contains unknown or write-related
arc1.*keys. - [ ] The effective authorization mode matches the deployment decision on every process. Enforced mode has no independent single-target connection or shared-identity app that defeats that boundary.
- [ ] Enabled candidate count (standard access) or total ARC-related candidate count (enforced) is 256 or fewer; enforced full catalog fits 512 KiB.
- [ ] If opting in, exact/disjoint-user, explicit all-target, missing/malformed grants, Admin-without-execution, refresh and client-catalog checks passed; IAM reviewed the global capability × target union.
- [ ] Admin
SAPTargetsshows no duplicate, shadow, quarantine, or unexpected policy narrowing. - [ ] PP-only scaled deployments report the same registry revision on every instance; Basic-enabled deployments have exactly one instance.
- [ ] Viewer, unmapped-user, SAP-unauthorized, broken-PP, changed-destination, and (if enabled) Basic credential rotation/lockout-protection cases were tested.
- [ ] Logs, audit sinks, tickets, and screenshots contain no destination secrets or raw SAP bodies.
- [ ] Rate and concurrency limits were reviewed with Basis.
- [ ] Lookalike production/non-production systems are separated if wrong-target reads are unacceptable.
- [ ] Admin scope is restricted to trusted operator sessions, especially beside writable
/mcp.
Deferred from v1¶
- multi-target writes, activation, transport mutation, and Git mutation;
- a full-write destination template;
- per-target capability pairing (target grants restrict routing, but functional scopes remain global);
- persisted per-user target availability;
- API-key or direct Entra/IAS OIDC access to multi-target routes;
- SaaS subscriber/provider and cross-subaccount discovery;
- S/4HANA Public Cloud/SAML assertion targets;
- a second technical/design-time destination per target;
- cache modes, plugins, optional UI, and hyperfocused mode;
- SAP-backed lint formatting/settings, transport topology (
layers/targets), and every transport mutation; - a browser HTML catalog or cookie/session login;
- per-target concurrency reservations; and
- live destination refresh without restart.
Repository maintainers can find the architecture, test matrix, and rollout contract in
docs/plans/destination-discovered-multi-target-v1.md and
docs/adr/0006-experimental-read-only-multi-target.md. The Basic shared-identity exception is
defined by docs/adr/0007-shared-basic-identity-for-read-only-multi-target.md.