diff --git a/content/momentum/4/4-lua-summary-table.md b/content/momentum/4/4-lua-summary-table.md
index c7cab4480..366e07deb 100644
--- a/content/momentum/4/4-lua-summary-table.md
+++ b/content/momentum/4/4-lua-summary-table.md
@@ -1,5 +1,5 @@
---
-lastUpdated: "10/05/2021"
+lastUpdated: "03/01/2025"
title: "Lua Functions Summary"
description: "This section contains tables of Lua functions Click the function name for details Table 64 1 Lua functions all Function Description Params Package Version Phases ac esmtp capability add Add a capability to the EHLO response name msys extended ac 4 0 connect ehlo ac esmtp capability remove Removes a..."
---
@@ -174,6 +174,8 @@ This section contains tables of Lua functions. Click the function name for detai
| [msys.unlock](/momentum/4/lua/ref-msys-unlock) – Releases a lock obtained via msys.lock | mutexname | msys | 4.0 | any |
| [msys.validate.dk.get_responsible_domain](/momentum/4/lua/ref-msys-validate-dk-get-responsible-domain) – This function requires module "dk_validate". "msg" is a mail message. "ctx" is the validation context. It returns the responsible domain for the current message | msg, ctx | msys.validate.dk | 4.0 | data, data_spool, data_spool_each_rcpt |
| [msys.validate.dk.sign](/momentum/4/lua/ref-msys-validate-dk-sign) – Sign a message using a Domain Key | msg, ctx, options | msys.validate.dk | 4.0 | core_data_validation |
+| [msys.validate.openarc.sign](/momentum/4/lua/ref-msys-validate-openarc-sign) – Sign a message using OpenARC | msg, options, [ar] | msys.validate.openarc | 5.0 | core_post_final_validation |
+| [msys.validate.openarc.verify](/momentum/4/lua/ref-msys-validate-openarc-verify) – Verify ARC sets | msg | msys.validate.openarc | 5.0 | data_spool, data_spool_each_rcpt |
| [msys.validate.opendkim.get_num_sigs](/momentum/4/lua/ref-msys-validate-opendkim-get-num-sigs) – Return the number of DKIM signatures | dkim | msys.validate.opendkim | 4.0 | data, data_spool, data_spool_each_rcpt |
| [msys.validate.opendkim.get_sig](/momentum/4/lua/ref-msys-validate-opendkim-get-sig) – Get a signature from a DKIM object | dkim, [num] | msys.validate.opendkim | 4.0 | data, data_spool, data_spool_each_rcpt |
| [msys.validate.opendkim.get_sig_canons](/momentum/4/lua/ref-msys-validate-opendkim-get-sig-canons) – Fetch the canonicalizers used for a DKIM signature | dkim_sig | msys.validate.opendkim | 4.0 | data, data_spool, data_spool_each_rcpt |
@@ -186,7 +188,7 @@ This section contains tables of Lua functions. Click the function name for detai
| [msys.validate.opendkim.get_sig_selector](/momentum/4/lua/ref-msys-validate-opendkim-get-sig-selector) – Fetch the selector associated with a DKIM signature | dkim_sig | msys.validate.opendkim | 4.0 | data, data_spool, data_spool_each_rcpt |
| [msys.validate.opendkim.get_sig_signalg](/momentum/4/lua/ref-msys-validate-opendkim-get-sig-signalg) – Return the signing algorithm as a string | dkim_sig | msys.validate.opendkim | 4.0 | data, data_spool, data_spool_each_rcpt |
| [msys.validate.opendkim.sign](/momentum/4/lua/ref-msys-validate-opendkim-sign) – Sign a message using OpenDKIM | msg, vctx, [options] | msys.validate.opendkim | 4.0 | core_final_validation |
-| [msys.validate.opendkim.verify](/momentum/4/lua/ref-msys-validate-opendkim-verify) – Verify an DKIM signature | m | msys.validate.opendkim | 4.0 | data, data_spool, data_spool_each_rcpt |
+| [msys.validate.opendkim.verify](/momentum/4/lua/ref-msys-validate-opendkim-verify) – Verify an DKIM signature | msg | msys.validate.opendkim | 4.0 | data, data_spool, data_spool_each_rcpt |
| [sess:request_add_header](/momentum/4/lua/ref-sess-request-add-header) – Set the header of an HTTP session | header, value, replace | msys.httpclnt | 4.0 | http_request_eval |
| [sess:request_delete_header](/momentum/4/lua/ref-sess-request-delete-header) – Delete a header from an HTTP session | header | msys.httpclnt | 4.0 | http_request_eval |
| [sess:request_finalize](/momentum/4/lua/ref-sess-request-finalize) – Finalize changes to an HTTP request | update | msys.httpclnt | 4.0 | http_request_eval |
diff --git a/content/momentum/4/eol-policy.md b/content/momentum/4/eol-policy.md
index 970354761..e46193da8 100644
--- a/content/momentum/4/eol-policy.md
+++ b/content/momentum/4/eol-policy.md
@@ -1,5 +1,5 @@
---
-lastUpdated: '11/06/2024'
+lastUpdated: '03/01/2025'
title: 'End of Life Policy'
description: 'This document provides the latest version of the formal end-of-life policy for releases of software from Message Systems.'
---
@@ -43,8 +43,14 @@ Momentum version 4 became GA on April 15, 2014. Therefore:
- Maintenance for all versions of Momentum 3 ended on December 31, 2018.
- Support for all versions of Momentum 3 ended on December 31, 2018.
-## MOMENTUM 4 GA DATES
+## MOMENTUM 4 END-OF-LIFE DATE
+Momentum version 5 became GA on March 1, 2025. Therefore:
+
+- Maintenance for all versions of Momentum 4 will end on March 1, 2026.
+- Support for all versions of Momentum 4 will end on March 1, 2027.
+
+## MOMENTUM 4 AND MOMENTUM 5 GA DATES
| Update and Maintenance Versions | GA | End of Maintenance | End of Support |
| ------------------------------- | ---------- | ------------------ | -------------- |
@@ -53,15 +59,16 @@ Momentum version 4 became GA on April 15, 2014. Therefore:
| Momentum 4.2.x | 2015/8/3 | 2020/6/30 | 2021/6/30 |
| Momentum 4.3.x | 2019/3/5 | 2022/9/3 | 2023/9/3 |
| Momentum 4.4.x | 2021/9/3 | 2024/10/20¹ | 2024/12/31³ |
-| Momentum 4.5.0 | 2023/10/5 | 2024/12/19² | TBD |
+| Momentum 4.5.0 | 2023/10/5 | 2024/12/19² | 2027/3/1 |
| Momentum 4.6.0 | 2023/10/20 | 2024/12/19 | 2024/12/31³ |
-| Momentum 4.7.0 | 2023/12/19 | 2025/10/17 | TBD |
-| Momentum 4.8.0 | 2024/10/17 | TBD | TBD |
+| Momentum 4.7.0 | 2023/12/19 | 2025/10/17 | 2027/3/1 |
+| Momentum 4.8.0 | 2024/10/17 | 2026/3/1 | 2027/3/1 |
+| **Momentum 5.0.0** | 2025/3/1 | TBD | TBD |
> ¹ Momentum 4.4.x was superseded by 4.6, which was the last version supporting CentOS 7.
>
> ² Momentum 4.5 was the first version supporting RHEL 8, and was superseded by 4.7.
>
-> ³ Given the EOL of CentOS 7 operating system on June 30, 2024, all GA and Maintenance releases of Momentum 4 supporting that platform will be supported until **December 31, 2024**.
+> ³ Given the EOL of CentOS 7 operating system on June 30, 2024, maintenance and support for all GA and Maintenance releases of Momentum 4 supporting that platform ended on **December 31, 2024**.
[Previous version (December 10, 2012)](/momentum/4/eol-policy-2012).
diff --git a/content/momentum/4/hooks/core-post-final-validation.md b/content/momentum/4/hooks/core-post-final-validation.md
new file mode 100644
index 000000000..0af6da8f5
--- /dev/null
+++ b/content/momentum/4/hooks/core-post-final-validation.md
@@ -0,0 +1,83 @@
+---
+lastUpdated: "11/26/2024"
+title: "post_final_validation"
+description: "hook invoked after the normal final validation"
+---
+
+
+## Name
+
+post_final_validation — This hook is invoked after the normal
+[final_validation](/momentum/3/3-api/hooks-core-final-validation) hook
+
+## Synopsis
+
+`#include "hooks/core/final_validation.h"`
+
+`int core_post_final_validation(void closure, ec_message *msg, accept_construct *ac, valiate_context *ctx)`
+
+
+## Description
+
+This hook is invoked right after the
+[final_validation](/momentum/3/3-api/hooks-core-final-validation) hook. Its return value
+does not have significance for now.
+This hook is added as the absolute last point before writing the message to spool for delivery.
+It guarantees that operations implemented in this hook will happen after the operations done in
+`final_validation`.
+To avoid undefined ordering between multiple implementations of the same hook, you shall have at most
+ one implementation for this hook.
+> It's the recommended hook point for ARC signing/sealing.
+
+
+**Parameters**
+
+The parameters from this hook are the same as the ones for `final_validation` hook.
+
+
+
+- closure
+
+-
+
+A pointer to the closure function.
+
+
+
+- msg
+
+-
+
+A pointer to an ec_message struct. For documentation of this data structure see [“ec_message”](/momentum/3/3-api/structs-ec-message)
+
+
+
+- ac
+
+-
+
+The `accept_construct` struct. For documentation of this data structure see [“accept_construct”](/momentum/3/3-api/structs-accept-construct)
+
+
+
+- ctx
+
+-
+
+The `validate_context` struct. For documentation of this data structure see [“validate_context”](/momentum/3/3-api/structs-validate-context)
+
+
+
+
+
+**Return Values**
+
+This hook returns `int`, but for now the return value has no significance, i.e. it is not checked in
+the caller.
+
+**Threading**
+
+This hook will be called in any thread.
+
+
+
diff --git a/content/momentum/4/hooks/index.md b/content/momentum/4/hooks/index.md
index cac445446..24c2ab346 100644
--- a/content/momentum/4/hooks/index.md
+++ b/content/momentum/4/hooks/index.md
@@ -1,6 +1,6 @@
---
-lastUpdated: "10/05/2021"
-title: "Category File"
+lastUpdated: "11/26/2024"
+title: "Hook Points and C Functions Reference"
type: "custom"
name: "Hook Points and C Functions Reference"
description: "This chapter includes hook point and C function reference material that is specific to Momentum 4 Hook points and C functions that are common to Momentum 4 and Momentum 3 are provided in the Momentum 3 x documentation For hook points see the C API For C functions see the..."
@@ -11,6 +11,7 @@ description: "This chapter includes hook point and C function reference material
|---------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------|
| [msg_gen_data_spool](/momentum/4/hooks/msg-gen-data-spool) | This hook is invoked after a message has been generated by the msg_gen module |
| [config_rsrc_setup](/momentum/4/hooks/config-rsrc-setup) | Register a resource |
+| [core_post_final_validation](/momentum/4/hooks/core-post-final-validation) | Same usage as but invoked right after the `core_final_validation` hook |
| [ec_config_rsrc_get](/momentum/4/apis-ec-config-rsrc-get) | Return a resource list blobject from the configuration system |
| [ec_httpsrv_register_auth](/momentum/4/apis-ec-httpsrv-register-auth) | Register an HTTP handler for authenticating a URI |
| [ec_httpsrv_request_local_address](/momentum/4/apis-ec-httpsrv-request-local-address) | Returns the local IP address from the current session |
diff --git a/content/momentum/4/lua/index.md b/content/momentum/4/lua/index.md
index aa963d5e9..342fd1a7f 100644
--- a/content/momentum/4/lua/index.md
+++ b/content/momentum/4/lua/index.md
@@ -1,5 +1,5 @@
---
-lastUpdated: "10/05/2021"
+lastUpdated: "03/01/2025"
title: "Category File"
type: "custom"
name: "Lua Functions Reference"
@@ -191,6 +191,8 @@ description: "This section details all Lua functions Functions are ordered alpha
| [msys.tls_params.set](/momentum/4/lua/ref-msys-tls-params-set) | Set a tls parameter string on a per connection basis |
| [msys.validate.dk.get_responsible_domain](/momentum/4/lua/ref-msys-validate-dk-get-responsible-domain) | Return the domain responsible for the current message |
| [msys.validate.dk.sign](/momentum/4/lua/ref-msys-validate-dk-sign) | Sign a message using a Domain Key |
+| [msys.validate.openarc.sign](/momentum/4/lua/ref-msys-validate-openarc-sign) | Sign a message using OpenARC |
+| [msys.validate.openarc.verify](/momentum/4/lua/ref-msys-validate-openarc-verify) | Verify ARC sets |
| [msys.validate.opendkim.get_num_sigs](/momentum/4/lua/ref-msys-validate-opendkim-get-num-sigs) | Return the number of DKIM signatures |
| [msys.validate.opendkim.get_sig](/momentum/4/lua/ref-msys-validate-opendkim-get-sig) | Get a signature from a DKIM object |
| [msys.validate.opendkim.get_sig_canons](/momentum/4/lua/ref-msys-validate-opendkim-get-sig-canons) | Fetch the canonicalizers used for a signature |
diff --git a/content/momentum/4/lua/ref-msys-validate-openarc-sign.md b/content/momentum/4/lua/ref-msys-validate-openarc-sign.md
new file mode 100644
index 000000000..cd9f93db9
--- /dev/null
+++ b/content/momentum/4/lua/ref-msys-validate-openarc-sign.md
@@ -0,0 +1,149 @@
+---
+lastUpdated: "11/26/2024"
+title: "msys.validate.openarc.sign"
+description: "msys validate openarc sign seal add ARC set headers"
+---
+
+
+## Name
+
+msys.validate.openarc.sign — builds and adds the ARC set headers into an email.
+
+msys.validate.openarc.seal - synonym of `msys.validation.openarc.sign`.
+
+## Synopsis
+
+`msys.validate.openarc.sign(msg, options, ar)`
+
+`msys.validate.openarc.seal(msg, options, ar)`
+
+```
+msg: userdata, ec_message type
+options: table
+ar: string, optional. It's the message's authentication assessment to be copied as-is into the AAR header.
+
+```
+
+## Description
+
+This function acquires ARC chain status (i.e. `cv`) from `ec_message` context variable `arc_cv`. The `cv`
+ will be used in the AS (ARC-Seal) header, and combined with authentication assessments from other
+ methods (e.g. SPF, DKIM, etc) defined by the `ar` and put into the AAR (ARC-Authentication-Results)
+ header. This function signs and seals the message by adding the AMS (ARC-Message-Signature) and AS
+ (ARC-Seal) headers, using the signing mechanism defined in the `options` table.
+
+If `ec_message` context variable `arc_cv` is not set when the function is called, the function will do an
+ internal ARC validation (to set the `arc_cv`), followed by the regular `cv` based signing.
+
+This function requires the [`openarc`](/momentum/4/modules/openarc) module.
+
+Enable this function with the statement `require('msys.validate.openarc')`.
+
+This function takes the following parameters:
+
+* `msg` - mail message to sign
+
+* `options` - table defines the options for signature generation/signing:
+
+ * `signing_domain` – signing domain
+
+ * `selector` – signing selector
+
+ * `authservid` – authentication service identifier, as
+ [authserv-id](https://datatracker.ietf.org/doc/html/rfc8601#section-2.5) defined in RFC.
+
+ If not set, will be defaulted to the hostname.
+
+ * `header_canon` – header canonicalization setting.
+
+ Supported values are `relaxed`, `simple`. Defaults to `relaxed`.
+
+ * `body_canon` – body canonicalization setting
+
+ Supported values are `relaxed`, `simple`. Defaults to `relaxed`.
+
+ * `digest` – signing algorithm digest setting.
+
+ Supported values are `rsa-sha1` and `rsa-sha256`. Defaults to `rsa-sha256`.
+
+ * `keyfile` – signing key file
+
+ * `keybuf` – signing key
+
+ Must contain the PEM encoded private key to use for signing the
+ message. This must be a contiguous string, with no line breaks and no white spaces, without the
+ `BEGIN` and `END` tags that are found in the key file itself. The format is similar to the
+ format used for OpenDKIM signing.
+
+ If not defined, will be built from the `keyfile`.
+
+ * `headerlist` – colon-separated list of headers to sign
+
+ * `oversign_headerlist` – colon-separated list of headers for over signing
+
+ * `skip_ar_header_update` – if set, no update to the AR (Authentication-Results) header.
+
+ If not set, Momentum will append the ARC verification result (e.g. `arc=pass`) to
+ the existing AR header or create one if it does not exist.
+
+* `ar` - authentication assessment to be copied as-is into the AAR (ARC-Authentication-Results) header.
+
+ If not provided, Momentum will take the value from the existing `Authentication-Results` header.
+ Momentum appends this value with the ARC verification result (e.g. `arc=pass`) and uses it to
+ build the AAR header.
+
+
+### Note
+
+Since ARC sealing must not happen until all potential modification of a message is done, if you
+ already have implementations in some other validation phases/hooks, this function
+ should be invoked in the `post_final_validation` stage to guarantee that it is called
+ after all the other hook implementations.
+
+The function would cause the `ec_message` context variable `arc_seal` to be set:
+
+`ok`: ARC signing/sealing is done, and ARC set headers are added.
+
+`skip`: ARC signing/sealing is skipped, because the ARC chain already fails before reaching the
+ current MTA.
+
+If the context variable `arc_seal` of the `ec_message` is not set, it indicates an unexpected ARC
+ signing/sealing failure, e.g. due to mis-configuration. The error reason is logged in paniclog.
+
+
+
+### Example
+
+
+```
+require("msys.core");
+require("msys.validate.openarc");
+local mod = {};
+
+function mod:core_post_final_validation(msg, accept, vctx)
+ local sealer = {}
+ sealer.signing_domain = "sparkpost.com"
+ sealer.selector = "dkim-s1024"
+ sealer.keyfile = "path-to-keyfile"
+ sealer.headerlist = "From:Subject:Date:To:MIME-Version:Content-Type"
+ sealer.oversign_headerlist = "From:To:Subject"
+
+ msys.validate.openarc.sign(msg, sealer)
+
+ -- check sign/seal result
+ local ok = msg:context_get(msys.core.ECMESS_CTX_MESS, "arc_seal")
+ if ok == nil or ok == '' then
+ print("ARC seal failed. No ARC set add! Check paniclog for reasons.")
+ elseif ok == "skip" then
+ print("ARC seal skipped. No ARC set add: ARC chain failed before reaching me.")
+ else
+ print("ARC seal ok. ARC set added!")
+ end
+end
+
+msys.registerModule("openarc_sign", mod);
+```
+
+## See Also
+
+[msys.validate.openarc.verify](/momentum/4/lua/ref-msys-validate-openarc-verify)
diff --git a/content/momentum/4/lua/ref-msys-validate-openarc-verify.md b/content/momentum/4/lua/ref-msys-validate-openarc-verify.md
new file mode 100644
index 000000000..aa67dd306
--- /dev/null
+++ b/content/momentum/4/lua/ref-msys-validate-openarc-verify.md
@@ -0,0 +1,63 @@
+---
+lastUpdated: "11/26/2024"
+title: "msys.validate.openarc.verify"
+description: "msys validate openarc verify Verify ARC sets headers"
+---
+
+
+## Name
+
+msys.validate.openarc.verify — Verifies ARC set headers in an email, and stores the verification results
+(`none/pass/fail`) into the email's context variable.
+
+## Synopsis
+
+`msys.validate.openarc.verify(msg)`
+
+`msg: userdata, ec_message type`
+## Description
+
+This function validates the ARC set headers contained in the input message. The validation result
+will be stored as string value (`none` or `pass` or `fail`) in the `ec_message`'s context variable
+of `arc_cv`. A caller can take actions (e.g. disposition of the message) based on the validation
+result.
+
+This function requires the [`openarc`](/momentum/4/modules/openarc) module.
+
+Enable this function with the statement `require('msys.validate.openarc')`.
+
+### Note
+
+After being called, this function always sets the `ec_message` context variable `arc_cv` to one of
+ the values: `none`, `pass`, `fail`. Unexpected `fail` cases are logged into paniclog.
+
+This function invokes dns lookup for signature validation. It's recommended to invoke it from a hook
+which would not block Momentum's main tasks, e.g. from the `validate_data_spool` or the
+ `validate_data_spool_each_rcpt` hook.
+
+
+### Example
+
+
+```
+require("msys.core");
+require("msys.extended.message");
+require("msys.validate.openarc");
+local mod = {};
+
+function mod:validate_data_spool_each_rcpt(msg, ac, vctx)
+ msys.validate.openarc.verify(msg)
+ local cv = msg:context_get(msys.core.ECMESS_CTX_MESS, "arc_cv")
+ if cv then
+ print("ARC validation result: ", cv)
+ else
+ print("Failed to do ARC validation. Check paniclog for reasons.")
+ end
+end
+
+msys.registerModule("openarc_verify", mod);
+```
+
+## See Also
+
+[msys.validate.openarc.sign](/momentum/4/lua/ref-msys-validate-openarc-sign)
diff --git a/content/momentum/4/modules/index.md b/content/momentum/4/modules/index.md
index 164907132..7514c8398 100644
--- a/content/momentum/4/modules/index.md
+++ b/content/momentum/4/modules/index.md
@@ -1,5 +1,5 @@
---
-lastUpdated: "10/05/2021"
+lastUpdated: "03/01/2025"
title: "Category File"
type: "custom"
name: "Modules Reference"
@@ -60,6 +60,7 @@ description: "Table of Contents 71 1 Introduction 71 2 ac auth Authentication Ha
| [msgc](/momentum/4/modules/msgc) | Message Systems Group Communication |
| [msg_gen](/momentum/4/modules/msg-gen) | Message Generation |
| [mxip](/momentum/4/modules/mxip) | IP Addresses In MX Records |
+| [openarc](/momentum/4/modules/openarc) | Open Source ARC |
| [opendkim](/momentum/4/modules/opendkim) | Open Source DKIM |
| [outbound_audit](/momentum/4/modules/outbound-audit) | Outbound traffic analytics |
| [outbound_smtp_auth(modules.outbound_smtp_auth.php) |
diff --git a/content/momentum/4/modules/openarc.md b/content/momentum/4/modules/openarc.md
new file mode 100644
index 000000000..338ae4e50
--- /dev/null
+++ b/content/momentum/4/modules/openarc.md
@@ -0,0 +1,174 @@
+---
+lastUpdated: "11/26/2024"
+title: "openarc – Open Source ARC"
+description: "The openarc module wraps the open source libopenarc API into Momentum to provide Momentum APIs to do ARC validation verification signature signing and sealing..."
+---
+
+ARC is an acronym for Authenticated Received Chain. It’s a technology protocol defined in
+[RFC8617](https://datatracker.ietf.org/doc/html/rfc8617). It provides an authenticated "chain of
+custody" for a message, allowing each entity that handles the message to see what entities handled
+it before and what the message's authentication assessment was at each step in the handling flow.
+
+The openarc module adds ARC capability to Momentum. It provides Lua and C APIs for
+ARC validation on a received email, and ARC siging and sealing on an outgoing email.
+When the module is enabled, ARC validation and signing/sealing can be achieved through calling these APIs from hook policies.
+
+
+## Configuration
+
+You need to enable the openarc module in the ecelerity configuration file to use the feature:
+
+```
+openarc {}
+```
+
+The only configuration option available to the `openarc` module is `debug_level`.
+
+
+## Lua APIs and examples
+
+[msys.validate.openarc.verify](/momentum/4/lua/ref-msys-validate-openarc-verify)
+
+[msys.validate.openarc.sign](/momentum/4/lua/ref-msys-validate-openarc-sign)
+
+
+## C APIs
+
+All the related C structures and C API functions are defined in the header file
+ `validate/ec_openarc.h`. Please refer to the header file for the usage of the C structures and
+ functions. Please contact support if further assistance is needed.
+
+
+## Hook points to invoke the APIs
+
+Invoke `msys.validate.openarc.verify` to do ARC verification on a received message. It would verify
+the existing ARC headers, including the AS (ARC Seal) and the AMS (ARC Message Signature). ARC
+verification shall be done before any potential message modifications, in `validate_data_spool` or
+[`validate_data_spool_each_rcpt`](/momentum/3/3-api/hooks-core-validate-data-spool-each-rcpt) hook.
+
+Invoke `msys.validate.openarc.sign` to do ARC signing/sealing to add the ARC headers. It should
+ happen after all possible message modifications are done, in the regular
+ [`final_validation`](/momentum/3/3-api/hooks-core-final-validation) hook, or the new
+ [`post_final_validation`](/momentum/4/hooks/core-post-final-validation) hook.
+ Any message modification after `msys.validate.openarc.sign` is called can break the integrity of
+ the ARC headers added during ARC signing.
+
+Since ARC signing requires the ARC chain verification result (aka `cv`). `msys.validate.openarc.sign`
+ will get the `cv` value from the `ec_message` context variable `arc_cv` for signing. If `arc_cv` is not
+ set, indicating a not-yet-done ARC verification, `msys.validate.openarc.sign` will do ARC verification
+ implicitly.
+
+If message modification is expected, an MTA shall call `msys.validate.openarc.verify` first (to get
+ `arc_cv` set) and then `msys.validate.openarc.sign` later in a different hooks, as recommended above.
+
+If there is absolutely no message modification, e.g. for a passthrough MTA which doesn't alter the
+message other than ARC signing, calling `msys.validate.openarc.sign` alone can have some performance
+benefits: the message will be scanned once for both ARC verification and signing.
+
+### Example 1:
+The following policies define an intermediate MTA which does ARC signing and can potentially
+ modify the email, e.g. through DKIM signing, engagement tracking insertion and modification, etc.
+ In such case, ARC verify needs to happen first, followed by the logic to alter the message (e.g.
+ DKIM signing in the example), and then finally ARC sign at the last.
+
+```
+require("msys.core");
+require("msys.extended.message");
+require("msys.validate.openarc");
+local mod = {};
+
+function mod:validate_data_spool(msg, ac, vctx)
+ -- do ARC verify
+ msys.validate.openarc.verify(msg)
+ local cv = msg:context_get(msys.core.ECMESS_CTX_MESS, "arc_cv")
+ if cv then
+ print("ARC validation result: ", cv)
+ else
+ print("Failed to do ARC validation. Check paniclog for reasons.")
+ end
+end
+
+function mod:core_final_validation(msg, accept, vctx)
+ -- do DKIM signing
+ local base_domain = 'ectest.example.com';
+ local header_canon = 'relaxed';
+ local body_canon = 'relaxed';
+ local digest = 'rsa-sha1';
+ local identity = '\@ectest.example.com';
+ local selector = 'dkim-s1024';
+ local key_file = '/opt/msys/ecelerity/etc/conf/default/dk/ectest.example.com/dkim-s1024.key';
+ local body_length_limit = 0;
+
+ local options = {};
+ options["base_domain"] = base_domain
+ options["header_canon"] = header_canon
+ options["body_canon"] = body_canon
+ options["digest"] = digest
+ options["selector"] = selector
+ options["keyfile"] = key_file
+ options["identity"] = identity
+
+ msys.validate.opendkim.sign(msg, vctx, options);
+end
+
+function mod:core_post_final_validation(msg, accept, vctx)
+ -- do ARC sign
+ local sealer = {}
+ sealer.signing_domain = "sparkpost.com"
+ sealer.selector = "dkim-s1024"
+ sealer.keyfile = "path-to-keyfile"
+ sealer.headerlist = "From:Subject:Date:To:MIME-Version:Content-Type:DKIM-Signature"
+ sealer.oversign_headerlist = "From:To:Subject"
+
+ msys.validate.openarc.sign(msg, sealer)
+
+ -- check sign/seal result
+ local ok = msg:context_get(msys.core.ECMESS_CTX_MESS, "arc_seal")
+ if ok == nil or ok == '' then
+ print("ARC seal failed. No ARC set add! Check paniclog for reasons.")
+ elseif ok == "skip" then
+ print("ARC seal skipped. No ARC set add: ARC chain failed before reaching me.")
+ else
+ print("ARC seal ok. ARC set added!")
+ end
+end
+
+msys.registerModule("arc_sign", mod);
+```
+
+### Example 2:
+The following policy defines an intermediate MTA relay which does not modify the message other than ARC signing.
+ In such case, ARC verify and ARC sign can be done at the same time, in any hook in DATA phase
+ which does not block the main tasks.
+
+```
+require("msys.core");
+require("msys.validate.openarc");
+local mod = {};
+
+function mod:core_final_validation(msg, accept, vctx)
+ -- do ARC signing (will trigger ARC verification implicitly)
+ local sealer = {}
+ sealer.signing_domain = "sparkpost.com"
+ sealer.selector = "dkim-s1024"
+ sealer.keyfile = "path-to-keyfile"
+ sealer.headerlist = "From:Subject:Date:To:MIME-Version:Content-Type"
+ sealer.oversign_headerlist = "From:To:Subject"
+
+ msys.validate.openarc.sign(msg, sealer)
+
+ -- check sign/seal result
+ local ok = msg:context_get(msys.core.ECMESS_CTX_MESS, "arc_seal")
+ if ok == nil or ok == '' then
+ print("ARC seal failed. No ARC set add! Check paniclog for reasons.")
+ elseif ok == "skip" then
+ print("ARC seal skipped. No ARC set add: ARC chain failed before reaching me.")
+ else
+ print("ARC seal ok. ARC set added!")
+ end
+end
+
+
+msys.registerModule("arc_sign", mod);
+```
+
diff --git a/content/momentum/4/modules/spf.md b/content/momentum/4/modules/spf.md
index f1a61e240..5f56b4eb1 100644
--- a/content/momentum/4/modules/spf.md
+++ b/content/momentum/4/modules/spf.md
@@ -1,5 +1,5 @@
---
-lastUpdated: "03/26/2020"
+lastUpdated: "02/01/2025"
title: "spf Modules – spf_macros, spf_v1, and senderid (SPF v2)"
description: "Sender Policy Framework SPF is an emerging standard for sender based authentication which provides a framework for administrators through DNS TXT records to specify authorized senders for the domains they control SP Fv 1 performs validation on the domain found in the envelope sender sometimes defined as the MAIL FROM..."
---
@@ -98,6 +98,16 @@ Set the default rule for a domain not implementing SPF. The default behavior is
+`delay_check = false`
+
+
+
+_Introduced in Momentum 5.0._
+
+Postpones the SPF check until the `RCPTTO` phase. This might be useful when the received message is accepted by a relay webhook that does not perform a SPF validation.
+
+
+
`fail_code = 250`
@@ -334,4 +344,4 @@ The is strong-bad@email.example.com.
IPv6:
%{ir}.%{v}._spf.%{d2} 1.0.B.C.0.0.0.0.
0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.B.D.0.1.0.0.2.ip6._spf.example.com
-```
\ No newline at end of file
+```
diff --git a/content/momentum/4/modules/summary-all-modules.md b/content/momentum/4/modules/summary-all-modules.md
index 22031ab1b..93c0aaaf8 100644
--- a/content/momentum/4/modules/summary-all-modules.md
+++ b/content/momentum/4/modules/summary-all-modules.md
@@ -1,5 +1,5 @@
---
-lastUpdated: "03/26/2020"
+lastUpdated: "03/01/2025"
title: "Modules Summary"
description: "All modules are listed alphabetically with a brief description Singleton modules are also identified The Version column indicates when the module was introduced into the system Note all modules listed as 4 0 modules were actually introduced in prior versions of Momentum The Auto column indicates whether a module is..."
---
@@ -70,6 +70,7 @@ All modules are listed alphabetically with a brief description. Singleton module
| [msgc_client](/momentum/4/modules/msgc) (*singleton*) | 4.0 | The client component of MSGC | | ✓ | | |
| [msgc_server](/momentum/4/modules/msgc) (*singleton*) | 4.0 | The server component of MSGC | | ✓ | | |
| [“mxip - IP Addresses In MX Records”](/momentum/4/modules/mxip) | 4.2 | Enable Momentum to deliver to domains with a textual IP address | | | | |
+| [“openarc – Open Source ARC”](/momentum/4/modules/openarc) | 5.0 | Validate/sign mail using ARC | | | ✓ | |
| [“opendkim – Open Source DKIM”](/momentum/4/modules/opendkim) | 4.0 | Validate/sign mail using DKIM signatures | | | ✓ | |
| [“outbound_audit – Outbound traffic analytics”](/momentum/4/modules/outbound-audit) | 4.0 | Provides time-series analytics on the behavior of receiving domains | | ✓ | | |
| [“outbound_smtp_auth”](/momentum/4/modules/outbound-smtp-auth) | 4.2 | Enables users to specify authentication parameters for a given set of messages | | | | |
diff --git a/content/momentum/changelog/5/5-0.md b/content/momentum/changelog/5/5-0.md
new file mode 100644
index 000000000..ab9423726
--- /dev/null
+++ b/content/momentum/changelog/5/5-0.md
@@ -0,0 +1,17 @@
+---
+lastUpdated: "03/01/2025"
+title: "Momentum 5.0 Changelog"
+description: "Momentum 5.0 was released on 2024-03-01. This section will list all of the major changes that happened with the release of Momentum 5.0. Depending on installation type, all changes may not be applicable"
+---
+
+This section will list all of the major changes that happened with the release of **Momentum 5.0**. Depending on installation type, all changes may not be applicable
+
+
+
+| Type | Ticket | Description |
+| --- | --- | --- |
+| Fix | EOP-106 | Potential memory leak with `msg:body_replace` |
+| Feature | | Support for [ARC](/momentum/4/modules/openarc) (Authenticated Received Chain) |
+| Feature | | New **msys-openarc** package with third-party OpenARC library (version 1.0.0-Beta3) *patched for Momentum* |
+| Feature | | New **spamassassin** module to integrate SpamAssassin with Momentum |
+| Feature | | On [SPF module](/momentum/4/modules/spf) (**spf_v1** and **senderid**), check can be postponed from MAILFROM to RCPTTO phase (new `delay_check` option) |
diff --git a/content/momentum/changelog/5/index.md b/content/momentum/changelog/5/index.md
new file mode 100644
index 000000000..ccc90d143
--- /dev/null
+++ b/content/momentum/changelog/5/index.md
@@ -0,0 +1,9 @@
+---
+lastUpdated: "03/01/2025"
+title: "Category File"
+type: "custom"
+name: "Momentum 5.x Changelogs"
+description: "Momentum 5.x Changelogs"
+---
+
+* [Momentum 5.0 Changelogs](/momentum/changelog/5/5-0)
diff --git a/content/momentum/changelog/index.md b/content/momentum/changelog/index.md
index 387983f7f..858edb37e 100644
--- a/content/momentum/changelog/index.md
+++ b/content/momentum/changelog/index.md
@@ -1,10 +1,11 @@
---
-lastUpdated: "04/08/2020"
+lastUpdated: "03/01/2025"
title: "Momentum Changelogs"
description: "Momentum Changelogs"
---
+- [Momentum 5.x Changelogs](/momentum/changelog/5)
- [Momentum 4.x Changelogs](/momentum/changelog/4)
- [Legacy Momentum Changelogs](/momentum/changelog/legacy)
----
\ No newline at end of file
+---
diff --git a/content/momentum/navigation.yml b/content/momentum/navigation.yml
index 9d5e7fd05..dba66c3fb 100644
--- a/content/momentum/navigation.yml
+++ b/content/momentum/navigation.yml
@@ -1966,6 +1966,11 @@
- link: /momentum/changelog
title: Changelog
items:
+ - link: /momentum/changelog/5
+ title: Momentum 5.x Changelog
+ items:
+ - link: /momentum/changelog/5/5-0
+ title: Momentum 5.0 Changelog
- link: /momentum/changelog/4
title: Momentum 4.x Changelog
items: