{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://www.modernedi.com/integration-api/configuration-as2-connection.schema.json",
  "title": "ModernEDI AS2 connection configuration",
  "description": "Portable desired state for one AS2 connection.",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "apiVersion",
    "kind",
    "metadata",
    "spec"
  ],
  "properties": {
    "apiVersion": {
      "$ref": "#/$defs/ConfigurationDocumentApiVersion"
    },
    "kind": {
      "type": "string",
      "enum": [
        "As2Connection"
      ]
    },
    "metadata": {
      "$ref": "#/$defs/ConfigurationResourceMetadata"
    },
    "spec": {
      "$ref": "#/$defs/ConfigurationAs2ConnectionSpec"
    }
  },
  "$defs": {
    "ConfigurationDocumentApiVersion": {
      "type": "string",
      "enum": [
        "modernedi.com/v1"
      ],
      "description": "Version of the portable configuration document contract used by export, planning, and apply."
    },
    "ConfigurationResourceMetadata": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "key"
      ],
      "properties": {
        "key": {
          "type": "string",
          "format": "uuid",
          "description": "Stable portable identity for this resource."
        }
      }
    },
    "ConfigurationAs2ConnectionSpec": {
      "description": "Complete resolved AS2 configuration without its server database id or API ETag. Exports reference public partner certificates beside connection.json. Inline public certificates are also accepted for API-authored and retained historical bundles. Private keys and secret locations are never included.",
      "type": "object",
      "additionalProperties": false,
      "required": [
        "environments",
        "outbound",
        "functionalAcknowledgment",
        "mdn",
        "cmsAlgorithmProtection",
        "digestCanonicalizationPolicy"
      ],
      "properties": {
        "environments": {
          "$ref": "#/$defs/ConfigurationAs2Environments"
        },
        "outbound": {
          "$ref": "#/$defs/As2ResolvedOutboundSettings"
        },
        "functionalAcknowledgment": {
          "$ref": "#/$defs/As2ResolvedFunctionalAcknowledgmentSettings"
        },
        "mdn": {
          "$ref": "#/$defs/As2ResolvedMdnSettings"
        },
        "cmsAlgorithmProtection": {
          "type": "boolean",
          "description": "Effective RFC 6211 `cmsAlgorithmProtect` compatibility setting."
        },
        "digestCanonicalizationPolicy": {
          "type": "string",
          "enum": [
            "AUTO",
            "CANONICALIZE",
            "PRESERVE"
          ],
          "description": "Effective inbound signature-verification treatment of MIME line endings."
        }
      }
    },
    "ConfigurationAs2Environments": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "production",
        "test"
      ],
      "properties": {
        "production": {
          "$ref": "#/$defs/ConfigurationAs2Environment"
        },
        "test": {
          "oneOf": [
            {
              "$ref": "#/$defs/ConfigurationAs2Environment"
            },
            {
              "type": [
                "object",
                "null"
              ],
              "enum": [
                null
              ]
            }
          ]
        }
      }
    },
    "ConfigurationAs2Environment": {
      "description": "An environment has either one inline public certificate or a file reference, never both. File references are confined to this connection. Production and Test may share one file; replacing it changes both environments' certificates.",
      "oneOf": [
        {
          "$ref": "#/$defs/As2PartnerEnvironmentResolved"
        },
        {
          "$ref": "#/$defs/ConfigurationAs2FileEnvironment"
        }
      ]
    },
    "As2PartnerEnvironmentResolved": {
      "description": "Persisted AS2 partner environment with all secure inbound-protection defaults resolved.",
      "allOf": [
        {
          "$ref": "#/$defs/As2PartnerEnvironment"
        },
        {
          "type": "object",
          "required": [
            "requireSignature",
            "requireEncryption"
          ]
        }
      ]
    },
    "As2PartnerEnvironment": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "as2Identifier",
        "publicCertificatePem"
      ],
      "properties": {
        "as2Identifier": {
          "type": "string",
          "minLength": 1,
          "description": "Partner's environment-specific AS2 identifier. ModernEDI matches it as inbound `AS2-From` and sends it as outbound `AS2-To`.",
          "example": "RETAILER_PROD"
        },
        "endpointUrl": {
          "type": [
            "string",
            "null"
          ],
          "format": "uri",
          "maxLength": 2000,
          "description": "Optional outbound destination. Omit it or use `null` for an inbound-only profile. When present, it must be an absolute HTTP or HTTPS partner destination URL without user information or a fragment. Endpoint workspaces must use HTTPS; plain HTTP requires Endpoint Plus, Static Outbound, Static Network, or Enterprise. The host must be publicly routable; local, private, link-local, multicast, carrier-grade NAT, documentation, benchmark, and other reserved address targets are rejected.",
          "example": "https://as2.retailer.example/receive"
        },
        "publicCertificatePem": {
          "type": "string",
          "description": "Exactly one PEM-encoded partner X.509 public certificate. ModernEDI canonicalizes it before storage.",
          "example": "-----BEGIN CERTIFICATE-----\nMIIB...partner-public-certificate...\n-----END CERTIFICATE-----"
        },
        "requireSignature": {
          "type": "boolean",
          "default": true,
          "description": "When `true` (the secure default), ModernEDI rejects non-MDN inbound messages for this environment unless the sender signature is present and successfully verified with the configured certificate. This policy belongs to the AS2 connection/environment and therefore applies to every attached partner on a shared or VAN connection. Set `false` only for a documented connection-wide exception. Omission on create resolves to `true`; resolved connection responses always include the field."
        },
        "requireEncryption": {
          "type": "boolean",
          "default": true,
          "description": "When `true` (the secure default), ModernEDI rejects non-MDN inbound messages for this environment unless their encrypted content was successfully decrypted. This policy belongs to the AS2 connection/environment and therefore applies to every attached partner on a shared or VAN connection. Set `false` only for a documented connection-wide exception. Omission on create resolves to `true`; resolved connection responses always include the field."
        }
      }
    },
    "ConfigurationAs2FileEnvironment": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "as2Identifier",
        "endpointUrl",
        "publicCertificatePath",
        "publicCertificateSha256",
        "requireSignature",
        "requireEncryption"
      ],
      "properties": {
        "as2Identifier": {
          "type": "string",
          "minLength": 1
        },
        "endpointUrl": {
          "type": [
            "string",
            "null"
          ],
          "format": "uri",
          "maxLength": 2000,
          "description": "The same publicly routable destination and workspace plan restrictions as the partner form apply."
        },
        "publicCertificatePath": {
          "type": "string",
          "pattern": "^\\./certificates/[a-z0-9][a-z0-9_-]{0,63}\\.pem(?![\\s\\S])",
          "example": "./certificates/shared.pem",
          "description": "Relative to connection.json. Production and Test may reference the same file. The file name uses 1-64 lowercase letters, digits, hyphens or underscores and starts with a letter or digit. No absolute paths, URLs, traversal, subdirectories, or other connections. Exports use shared.pem when both environments have the same certificate; otherwise production.pem and test.pem."
        },
        "publicCertificateSha256": {
          "$ref": "#/$defs/ConfigurationSha256"
        },
        "requireSignature": {
          "type": "boolean"
        },
        "requireEncryption": {
          "type": "boolean"
        }
      }
    },
    "ConfigurationSha256": {
      "type": "string",
      "pattern": "^[0-9a-f]{64}$",
      "description": "Lowercase hexadecimal SHA-256 digest.",
      "example": "30d7e671476880c8d357370bf9a7c21fc59f55d2435073e92763f61d1c72f749"
    },
    "As2ResolvedOutboundSettings": {
      "description": "Fully resolved outbound algorithms and compatibility settings; all fields are present in responses.",
      "allOf": [
        {
          "$ref": "#/$defs/As2OutboundTransportSettings"
        },
        {
          "type": "object",
          "required": [
            "signingAlgorithm",
            "encryptionAlgorithm",
            "compressionAlgorithm",
            "micAlgorithm",
            "micAlgorithmFormat"
          ]
        }
      ]
    },
    "As2OutboundTransportSettings": {
      "type": "object",
      "additionalProperties": false,
      "description": "Optional outbound AS2 algorithms and MIME-compatibility controls. Each omitted field receives its documented default.",
      "properties": {
        "signingAlgorithm": {
          "type": "string",
          "enum": [
            "SHA256WITHRSA",
            "SHA384WITHRSA",
            "SHA512WITHRSA",
            "SHA1WITHRSA"
          ],
          "default": "SHA256WITHRSA",
          "description": "CMS/S/MIME signature algorithm ModernEDI uses for signed outbound payloads, signed automatic X12 acknowledgments, and signed MDNs. Prefer `SHA256WITHRSA`; use `SHA1WITHRSA` only for a legacy partner that cannot verify SHA-2 signatures.",
          "example": "SHA256WITHRSA"
        },
        "encryptionAlgorithm": {
          "type": "string",
          "enum": [
            "AES256_CBC",
            "AES128_CBC",
            "DES_EDE3_CBC"
          ],
          "default": "AES256_CBC",
          "description": "CMS content-encryption algorithm for outbound AS2 payloads and any encrypted acknowledgments. Prefer `AES256_CBC`; `DES_EDE3_CBC` exists only for legacy partner interoperability.",
          "example": "AES256_CBC"
        },
        "compressionAlgorithm": {
          "type": "string",
          "enum": [
            "ZLIB"
          ],
          "default": "ZLIB",
          "description": "Compression algorithm used when an outbound AS2 message structure includes compression. `ZLIB` is the only supported customer-selectable value.",
          "example": "ZLIB"
        },
        "micAlgorithm": {
          "type": "string",
          "enum": [
            "SHA_1",
            "SHA_256",
            "SHA_512"
          ],
          "default": "SHA_256",
          "description": "Digest algorithm used to calculate and store ModernEDI's local content MIC for outbound X12 payloads and automatic X12 acknowledgments. This does not choose the CMS signature digest (`signingAlgorithm` does), the signed MIME `micalg` token format (`micAlgorithmFormat` does), or the `Received-content-MIC` algorithm used when ModernEDI returns an MDN for an inbound message; that comes from the sender's receipt request."
        },
        "micAlgorithmFormat": {
          "type": "string",
          "enum": [
            "RFC_5751",
            "RFC_3851"
          ],
          "default": "RFC_3851",
          "description": "Advanced partner-compatibility override for the S/MIME `Content-Type` `micalg` parameter on every signed MIME entity ModernEDI generates for this partner, including outbound X12 messages, automatic signed X12 acknowledgments, and the outer wrapper of signed MDNs. `RFC_5751` uses the newer hyphenated token format—for example, `sha-256`—while `RFC_3851` uses the older token `sha256`. Omit this field to use the compatibility-first `RFC_3851` default. This setting changes only the serialized notation of the signature digest selected by `signingAlgorithm` in that MIME parameter; it does not change the digest itself or the algorithm named inside `Received-content-MIC`. Change it only when the partner's AS2 profile or interoperability testing requires a particular token format."
        }
      }
    },
    "As2ResolvedFunctionalAcknowledgmentSettings": {
      "description": "Fully resolved MIME packaging for automatic X12 acknowledgments (997 or partner-enabled 999).",
      "allOf": [
        {
          "$ref": "#/$defs/As2FunctionalAcknowledgmentSettings"
        },
        {
          "type": "object",
          "required": [
            "messageStructure"
          ]
        }
      ]
    },
    "As2FunctionalAcknowledgmentSettings": {
      "type": "object",
      "additionalProperties": false,
      "description": "Optional automatic X12 acknowledgment MIME packaging for 997s and partner-enabled 999s. Omit the object or `messageStructure` to use `SIGNED_ENCRYPTED`.",
      "properties": {
        "messageStructure": {
          "type": "string",
          "enum": [
            "PLAIN",
            "SIGNED",
            "ENCRYPTED",
            "SIGNED_ENCRYPTED",
            "PLAIN_COMPRESSED",
            "SIGNED_COMPRESSED",
            "ENCRYPTED_COMPRESSED",
            "ENCRYPTED_COMPRESSED_SIGNED"
          ],
          "default": "SIGNED_ENCRYPTED",
          "description": "MIME signing, encryption, and compression structure used when ModernEDI automatically sends an X12 acknowledgment (997 or partner-enabled 999) to this partner."
        }
      }
    },
    "As2ResolvedMdnSettings": {
      "description": "Fully resolved Message Disposition Notification compatibility settings.",
      "allOf": [
        {
          "$ref": "#/$defs/As2MdnSettings"
        },
        {
          "type": "object",
          "required": [
            "encrypt",
            "forceSynchronousForErrors"
          ]
        }
      ]
    },
    "As2MdnSettings": {
      "type": "object",
      "additionalProperties": false,
      "description": "Optional MDN interoperability controls. Omitted values default to unencrypted MDNs and synchronous error dispositions.",
      "properties": {
        "encrypt": {
          "type": "boolean",
          "default": false,
          "description": "When true, ModernEDI attempts to encrypt MDNs returned for inbound messages with the partner certificate and configured outbound encryption algorithm. If MDN encryption itself fails, ModernEDI returns an unencrypted error MDN so the partner still receives a disposition."
        },
        "forceSynchronousForErrors": {
          "type": "boolean",
          "default": true,
          "description": "When true, an inbound processing failure or error is returned as a synchronous MDN even when the normal receipt flow is asynchronous."
        }
      }
    }
  }
}
