-
Notifications
You must be signed in to change notification settings - Fork 18
Testing Without Peppol Network
This page describes how to operate phoss AP for local or closed-circle testing — that is, without joining the official Peppol network (SML) and without performing live exchanges against real Peppol Service Providers.
A related guide for phase4 (the underlying AS4 engine) is available at phase4 Testing. phoss AP adds two constraints on top of phase4 that change the picture: a mandatory startup-time AP certificate chain check, and a mandatory SMP lookup for every outbound transaction.
No — not with the current configuration surface. phoss AP enforces two hard checks that reject any AP certificate that does not chain to one of the official Peppol CAs:
- At startup, the configured AP certificate is verified against
PeppolTrustedCA.peppolProductionAP()orPeppolTrustedCA.peppolTestAP()(depending onpeppol.stage). A self-signed certificate causes startup to fail withInitializationException(APServletInit.java#L271-L280). - On every outbound transmission, the remote AP certificate returned by the SMP is checked against the same Peppol CA set (
OutboundOrchestrator.java#L666-L667).
This is different from raw phase4, where the receiver-side check can be disabled per send.
The closest practical setup is therefore: use Peppol Test AP certificates on both ends (these are issued during the regular Peppol onboarding/testbed process) and replace the network — SML, SMP, and trust roots for SMP signatures — with components you control. The rest of this page describes that setup.
No. All outbound submission endpoints (POST /api/outbound/submit/..., POST /api/outbound/submit-sbd, POST /api/outbound/submit-s3) funnel into OutboundOrchestrator.processPendingOutbound(), which always performs NAPTR/SMP lookup before the AS4 send. There is no parameter to inject a pre-resolved endpoint URL and AP certificate.
For local testing this means a local SMP instance is required. The simplest option is phoss SMP, which can be run locally and configured to publish your test participant.
For a two-instance test (Instance A sending to Instance B) you need:
- Two Peppol Test AP certificates — one per AP instance. These are the standard certificates issued by the Peppol PKI for the Test environment.
-
A local SMP (e.g. phoss SMP) that:
- Publishes service group entries for the test participants you want to exchange messages between.
- Returns the URL and AP certificate of the receiving AP instance.
- Signs SMP responses with a key whose CA you control (this can be self-signed since the trust anchor is configurable — see below).
-
A custom SMP truststore (
.p12/.jks) containing the CA that signs your local SMP's responses. -
DNS resolution for the participants — either by registering them in a Peppol SML test instance (most realistic), or by directing
peppol.dns.serversto a DNS server you control that answers NAPTR queries for your participants.
# Must stay 'test' — 'prod' would require Production AP certificates
peppol.stage=test
# AP keystore — your Peppol Test AP certificate
org.apache.wss4j.crypto.merlin.keystore.type=pkcs12
org.apache.wss4j.crypto.merlin.keystore.file=keystore/your-test-ap.p12
org.apache.wss4j.crypto.merlin.keystore.password=...
org.apache.wss4j.crypto.merlin.keystore.alias=...
org.apache.wss4j.crypto.merlin.keystore.private.password=...
# AP truststore — keep the standard Peppol Test AP truststore.
# The other instance's AP certificate must also chain to the Peppol Test AP CA,
# so the bundled truststore already covers it.
org.apache.wss4j.crypto.merlin.truststore.type=pkcs12
org.apache.wss4j.crypto.merlin.truststore.file=truststore/2025/ap-test-truststore.p12
org.apache.wss4j.crypto.merlin.truststore.password=peppolThe SMP signature is verified against the truststore configured via smpclient.truststore.path. Replace the bundled Peppol Test SMP truststore with a custom truststore containing the CA that signs your local SMP:
smpclient.truststore.type=PKCS12
smpclient.truststore.path=keystore/local-smp-truststore.p12
smpclient.truststore.password=...Note: the AP certificate returned in the SMP response is still validated against PeppolTrustedCA.peppolTestAP() — i.e., the remote AP certificate the SMP publishes must be a real Peppol Test AP certificate. You can swap the SMP signer freely, but you cannot swap the remote AP CA.
The inbound SMP cross-check verifies that this AP is actually registered for the inbound receiver. For a closed-circle test where DNS/SML may not list your participants, set:
peppol.receiver-check.mode=noneThis disables the inbound SMP lookup; the AP will accept any inbound AS4 message whose signature is valid against the AP truststore and whose receiver participant is well-formed. Acceptable for testing — see Security Considerations before using anywhere else.
Alternatively, point the check at your local SMP:
peppol.receiver-check.mode=smp
peppol.smp.url=http://localhost:8080
phase4.endpoint.address=https://your-ap.example.com/as4If your local SMP is not registered in a real SML, outbound NAPTR lookups will fail. Either:
- Point
peppol.dns.serversat a private DNS server that publishes the NAPTR records pointing to your local SMP, or - Register the test participants in a Peppol SML test instance (the same SML you would use for testbed onboarding).
peppol.dns.servers=10.0.0.53If a given instance only needs to play one role, disable the other side to remove unused configuration:
# Receive-only AP (no outbound) — avoids needing an SMP for outbound at all
peppol.sending.enabled=false
# Send-only AP (no inbound)
peppol.receiving.enabled=falseA receive-only AP avoids the outbound SMP lookup entirely, which makes it the simplest configuration to validate inbound AS4 reception against a sender you control.
The least amount of moving parts. Use phase4 as the sender (where checkReceiverAPCertificate(false) and .receiverEndpointDetails(cert, url) allow bypassing SMP entirely), and phoss AP as a receive-only endpoint.
- Configure phoss AP with
peppol.sending.enabled=falseandpeppol.receiver-check.mode=none. - phase4 sender connects directly to the AP's
/as4endpoint with the AP's public Peppol Test certificate.
Full bidirectional flow.
- Two instances, each with its own Peppol Test AP certificate.
- One local SMP publishing both participants and pointing each participant at the correct AP's
phase4.endpoint.address. - Both instances configured with
smpclient.truststore.pathpointing at the truststore containing the local SMP's signing CA. -
peppol.receiver-check.mode=none(orsmppointed at the local SMP). -
peppol.dns.serverspointed at a DNS server that resolves the participants' NAPTR records to the local SMP — or use a real test SML.
- Self-signed AP certificates. Startup fails.
- Sending without an SMP. There is no API parameter to provide a pre-resolved endpoint URL + remote AP certificate. Every outbound transaction performs SMP/NAPTR lookup.
-
Outbound to a counterparty whose AP certificate is not Peppol-issued. The check at
OutboundOrchestrator.java:666-667rejects the remote certificate even if your SMP returns it.
- Configuration Properties — full property reference.
- Security Considerations — implications of disabling receiver checks.
- Peppol Specifics — Peppol-specific behaviors enforced by this AP.
- phase4 Testing — testing the AS4 layer in isolation.
It is appreciated if you star the GitHub project if you like it.
Donation link: https://paypal.me/PhilipHelger
- Home
- News and noteworthy
- Running phoss AP
- Architecture Overview
- API Specification
- Configuration Properties
- Code Lists
- Database Design Notes
- Maven Module Structure
- Runtime Extensions
- OpenTelemetry Integration
- Security Considerations
- Peppol Specifics
- Testing Without Peppol Network
- Known Users
- Migrating from phase4-peppol-standalone
- Contributing