{
  "schema": "aaes/capability-pack/1",
  "provider": "sap",
  "version": "1.0.0",
  "description": "SAP S/4HANA Cloud: read business partners, supplier invoices, purchase orders and journal entries, and create purchase orders that may be sent to suppliers.",
  "notes": "The endpoint host 'sap-instance.invalid' is a reserved non-production placeholder (an RFC 2606 reserved TLD): substitute the customer's own S/4HANA Cloud tenant host before enabling, in every endpoint, in every resource locator and in every egress allowlist entry. The allowlist matches exactly, so endpoints and allowlist must be substituted together, and substitution is a required deployment step — the reserved host being allowlisted does not make an unsubstituted pack safe to enable.\n\nThis pack registers only endpoints SAP's official documentation for SAP S/4HANA Cloud describes: the OData V4 Purchase Order API (service group api_purchaseorder_2, repository srvd_a2x, service purchaseorder, version 0001) for purchase order read and create, and the OData V2 services SAP documents for business partners (API_BUSINESS_PARTNER), supplier invoices (API_SUPPLIERINVOICE_PROCESS_SRV) and journal entry items (API_JOURNALENTRYITEMBASIC_SRV). SAP deprecated the OData V2 purchase order API in favour of the OData V4 service, which is why the purchase order capabilities register the V4 path; this pack makes no claim that OData V4 equivalents of the other three objects do not exist — it registers the services SAP documents for them.\n\nAll reads are collection reads only: single-record reads (A_BusinessPartner('...'), A_SupplierInvoice(SupplierInvoice='...',FiscalYear='...'), PurchaseOrder(PurchaseOrder='...')) exist in the APIs and are deliberately not registered.\n\nDocumented exclusions, framed as what this pack does not register: business partner create, update and delete (the Business Partner (A2X) service documents full CRUD); supplier invoice create, release and the single-invoice deep read (the Supplier Invoice service is documented as Create, Read, Release, Reverse with POST on A_SupplierInvoice); purchase order update and delete (SAP documents the V4 service as create, read, update and delete — this pack registers create and read only); journal entry posting (the SOAP service JournalEntryBulkCreationRequest_In and any other posting API); and every other OData service on the tenant.\n\nThe services are exposed through Communication Arrangements on the tenant, and each arrangement's inbound communication user carries only the authorizations of the scenarios it is assigned: the registration records the endpoint, not the tenant's authorization decision — a capability works only if the communication user is permitted the operation. Modifying requests against SAP Gateway require an X-CSRF-Token: the deployment's HTTP adapter must fetch one (x-csrf-token: Fetch) against the same service root before issuing the registered POST, and that adapter wiring is a deployment step, not something this pack performs.\n\nApproval classification: the collection reads sit at the minimum R0 tier of read. The purchase order create is registered at R3 declaring create and send: SAP documents that a purchase order subject to a release procedure cannot be outputted (printed or transmitted directly to the vendor) before release, but output determination and dispatch timing are tenant configuration, so on a tenant whose output management dispatches immediately on save with no release procedure the create can transmit the order to the supplier — the send effect is declared rather than assumed away.",
  "credential": {
    "secret_ref_id": "secret-ref-sap-s4-communication-user",
    "custody": "customer_vault",
    "inject": "header",
    "inject_name": "Authorization",
    "note": "Credentials of an inbound communication user on the customer's own S/4HANA Cloud tenant, held in the client's own secret manager. The stored material must be the complete Authorization header value (scheme included): 'Basic', one separating space, then the base64 of 'user:password' — 'Basic <base64>'. An external deployment process creates the communication user and the Communication Arrangements that publish these services (for example SAP_COM_0008 for the business partner service), rotates the password, and stores the renewed header value; the executor injects the stored value verbatim and performs no credential lifecycle itself. customer_vault is the only generally-supported production custody model here — identity_federation and customer_broker are refused at startup and inline is lab-only.\n\nPasswords expire under the tenant's password policy and a communication user can be locked or deleted at any time, which revokes access; an expired or revoked value fails closed.\n\nLeast privilege: assign the user only the communication scenarios that publish the services this pack registers, and nothing more. Authorization granularity: a communication scenario publishes its services to the assigned inbound user, and the operation-level authority the user then holds is whatever the scenario's business catalogs and authorization objects grant — scenario assignment alone does not deny individual CRUD or release operations inside a published service.\n\nThe deployment must therefore verify the residual authority of the assigned scenarios (for example, whether the purchase order scenario also authorizes the update and delete operations this pack does not register) rather than assume exclusion by registration; residual authority the scenario cannot remove is a reviewed deployment risk, not a pack control. This registration stores a Basic header; certificate-based or OAuth 2.0 inbound authentication, where the deployment supports it, is a separately reviewed authentication change, not an interchangeable alternative to this credential contract.\n\nReview rotation cadence before enabling.\n\nExecutor hygiene: the value must live only in executor memory for the lifetime of a call, must never be written to logs, traces or diagnostics, and must not appear in crash dumps; a deployment that cannot meet that bar must not enable the pack."
  },
  "capabilities": [
    {
      "capability_id": "sap.businesspartner.read",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R0",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "pii",
      "egress_allowlist": [
        "sap-instance.invalid"
      ],
      "endpoint": "https://sap-instance.invalid/sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartner",
      "method": "GET",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-sap-s4-communication-user",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "read"
      ],
      "resource_id": "sap-s4-businesspartners",
      "description": "Read the A_BusinessPartner collection of the Business Partner (A2X) OData service: business partner, customer and supplier master records with names, addresses and contact data, which are personal data. The registered path covers the collection read only — single-record reads (A_BusinessPartner('...')) and the related address, bank and role entity sets are not registered by this pack.\n\nThe host is a reserved placeholder: substitute the customer's tenant host before enabling.",
      "requires_review": true
    },
    {
      "capability_id": "sap.supplierinvoice.read",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R0",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "financial",
      "egress_allowlist": [
        "sap-instance.invalid"
      ],
      "endpoint": "https://sap-instance.invalid/sap/opu/odata/sap/API_SUPPLIERINVOICE_PROCESS_SRV/A_SupplierInvoice",
      "method": "GET",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-sap-s4-communication-user",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "read"
      ],
      "resource_id": "sap-s4-supplierinvoices",
      "description": "Read the A_SupplierInvoice collection of the Supplier Invoice OData service: supplier invoice headers with amounts, currencies, suppliers and payment data, classified as financial data. The registered path covers the collection read only — the single-invoice read (A_SupplierInvoice(SupplierInvoice='...',FiscalYear='...')) and the documented create and release operations are not registered by this pack.\n\nThe host is a reserved placeholder: substitute the customer's tenant host before enabling.",
      "requires_review": true
    },
    {
      "capability_id": "sap.purchaseorder.read",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R0",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "financial",
      "egress_allowlist": [
        "sap-instance.invalid"
      ],
      "endpoint": "https://sap-instance.invalid/sap/opu/odata4/sap/api_purchaseorder_2/srvd_a2x/sap/purchaseorder/0001/PurchaseOrder",
      "method": "GET",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-sap-s4-communication-user",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "read"
      ],
      "resource_id": "sap-s4-purchaseorders",
      "description": "Read the PurchaseOrder entity set of the OData V4 Purchase Order API (service group api_purchaseorder_2, repository srvd_a2x, service purchaseorder, version 0001): purchase order headers with suppliers, amounts and currencies, classified as financial data. The registered path covers the collection read only — single-record reads (PurchaseOrder(PurchaseOrder='...')) and the item, schedule-line and partner entity sets are not registered by this pack.\n\nThe host is a reserved placeholder: substitute the customer's tenant host before enabling.",
      "requires_review": true
    },
    {
      "capability_id": "sap.purchaseorder.create",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R3",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "financial",
      "egress_allowlist": [
        "sap-instance.invalid"
      ],
      "endpoint": "https://sap-instance.invalid/sap/opu/odata4/sap/api_purchaseorder_2/srvd_a2x/sap/purchaseorder/0001/PurchaseOrder",
      "method": "POST",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-sap-s4-communication-user",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "create",
        "send"
      ],
      "resource_id": "sap-s4-purchaseorders",
      "description": "Create one purchase order through the OData V4 Purchase Order API. SAP supports create, read, update, and delete through this service; this package registers only create and, separately, read.\n\nCreation can send the order to the supplier. SAP prevents output (printing or direct transmission) before approval when a release procedure applies. Otherwise, tenant output settings can dispatch the order immediately on save. The registration does not constrain those settings, so it declares create and send at R3.\n\nThe package registers no release, approval, update, or delete operation. That exclusion does not prevent a created order from triggering tenant workflows. Before POST, the deployment adapter must fetch an X-CSRF-Token from the same service root. Replace the reserved host with the customer's tenant host before enabling.",
      "requires_review": true
    },
    {
      "capability_id": "sap.journalentryitem.read",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R0",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "financial",
      "egress_allowlist": [
        "sap-instance.invalid"
      ],
      "endpoint": "https://sap-instance.invalid/sap/opu/odata/sap/API_JOURNALENTRYITEMBASIC_SRV/A_JournalEntryItemBasic",
      "method": "GET",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-sap-s4-communication-user",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "read"
      ],
      "resource_id": "sap-s4-journalentries",
      "description": "Read the A_JournalEntryItemBasic collection of the Journal Entry Item - Read (A2X) OData service: posted journal entry items with company code, G/L account, amounts and currencies, classified as financial data. The service is read-only; the registered path covers the collection read only — keyed single-item reads are not registered by this pack.\n\nThe host is a reserved placeholder: substitute the customer's tenant host before enabling.",
      "requires_review": true
    }
  ],
  "resources": [
    {
      "resource_id": "sap-s4-businesspartners",
      "kind": "api",
      "locator": "https://sap-instance.invalid/sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartner",
      "data_class": "pii",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN"
    },
    {
      "resource_id": "sap-s4-supplierinvoices",
      "kind": "api",
      "locator": "https://sap-instance.invalid/sap/opu/odata/sap/API_SUPPLIERINVOICE_PROCESS_SRV/A_SupplierInvoice",
      "data_class": "financial",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN"
    },
    {
      "resource_id": "sap-s4-purchaseorders",
      "kind": "api",
      "locator": "https://sap-instance.invalid/sap/opu/odata4/sap/api_purchaseorder_2/srvd_a2x/sap/purchaseorder/0001/PurchaseOrder",
      "data_class": "financial",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN"
    },
    {
      "resource_id": "sap-s4-journalentries",
      "kind": "api",
      "locator": "https://sap-instance.invalid/sap/opu/odata/sap/API_JOURNALENTRYITEMBASIC_SRV/A_JournalEntryItemBasic",
      "data_class": "financial",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN"
    }
  ],
  "review": {
    "state": "library",
    "date": "2026-09-22",
    "sources": [
      "https://help.sap.com/docs/SAP_S4HANA_CLOUD/bb9f1469daf04bd894ab2167f8132a1a/649d14483a984b788f3753ac88b37810.html (retrieved 2026-09-21)",
      "https://help.sap.com/docs/SAP_S4HANA_CLOUD/bb9f1469daf04bd894ab2167f8132a1a/c89eec80ec2043d980cb7b8c89e0a00a.html (retrieved 2026-09-21)",
      "https://help.sap.com/docs/SAP_S4HANA_CLOUD/bb9f1469daf04bd894ab2167f8132a1a/807238156726425dbd7f7ff8afc24da1.html (retrieved 2026-09-21)",
      "https://help.sap.com/docs/SAP_S4HANA_ON-PREMISE/8a57feade137489098f59374c06f1e0e/cf06b753128eb44ce10000000a174cb4.html (retrieved 2026-09-21)",
      "https://help.sap.com/docs/SAP_S4HANA_CLOUD/0e602d466b99490187fcbb30d1dc897c/0dd23a5023d14ddd9e1aa520db1ce141.html (retrieved 2026-09-21)",
      "https://help.sap.com/doc/ce01d82756b947a1a043a5d5a3204226/2302.500/en-US/WN_CE2302_EN.pdf (retrieved 2026-09-21)",
      "https://help.sap.com/doc/b870b6ebcd2e4b5890f16f4b06827064/2023.000/en-US/WN_OP2023_EN.pdf (retrieved 2026-09-21)",
      "https://help.sap.com/docs/SAP_S4HANA_CLOUD/bb9f1469daf04bd894ab2167f8132a1a/d8b16ace9227447c8c66086bc045a937.html (retrieved 2026-09-21)",
      "https://help.sap.com/docs/SAP_S4HANA_CLOUD/bb9f1469daf04bd894ab2167f8132a1a/7bc52558ef790a02e10000000a44147b.html (retrieved 2026-09-21)",
      "https://help.sap.com/docs/SAP_S4HANA_CLOUD/b978f98fc5884ff2aeb10c8fdeb8a43b/8aa29c6ac8234f9a9b975b3900aa002d.html (retrieved 2026-09-21)",
      "https://help.sap.com/docs/SAP_S4HANA_CLOUD/3c916ef10fc240c9afc594b346ffaf77/85043858ea0f9244e10000000a4450e5.html (retrieved 2026-09-21)",
      "https://userapps.support.sap.com/sap/support/knowledge/en/3492316 (retrieved 2026-09-21)",
      "https://github.com/SAP-samples/btp-kyma-multitenant-extension/blob/main/documentation/appendix/enable-odata-of-s4hana/README.md (retrieved 2026-09-21)",
      "https://community.sap.com/t5/application-development-and-automation-discussions/s-4hana-cloud-public-odata-v4-rest-api-and-purchasing-history/td-p/13894896 (retrieved 2026-09-21)",
      "https://userapps.support.sap.com/sap/support/knowledge/en/3698875 (retrieved 2026-09-21)",
      "https://docs.plaidcloud.com/reference/connectors/rest/s4hana-cloud/ (retrieved 2026-09-21)"
    ],
    "reviewer_id": "aaes-eng"
  }
}
