Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

### Fixed
- Correct FAPI header to `x-fapi-interaction-id` [PR #1557](https://github.com/3scale/APIcast/pull/1557) [THREESCALE-11957](https://issues.redhat.com/browse/THREESCALE-11957)

### Added
- Update APIcast schema manifest [PR #1550](https://github.com/3scale/APIcast/pull/1550)
- Update luarocks to v3.12.0 [PR #1555](https://github.com/3scale/APIcast/pull/1555)

### Removed

## [3.16.0] 2025-05-19

### Fixed
Expand Down
29 changes: 27 additions & 2 deletions gateway/src/apicast/policy/fapi/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@

The FAPI policy supports various features of the Financial-grade API (FAPI) standard.

* FAPI 1.0 Baseline Profile
* FAPI 1.0 Advance Profile
* [FAPI 1.0 Baseline Profile](https://openid.net/specs/openid-financial-api-part-1-1_0.html)
* [FAPI 1.0 Advance Profile](https://openid.net/specs/openid-financial-api-part-2-1_0.html)

## Example configuration

FAPI policy set the response header `x-fapi-interaction-id` to the value received from the corresponding FAPI client request header or to a RFC4122 UUID value if the request header was not provided.

```
"policy_chain": [
{ "name": "apicast.policy.fapi", "configuration": {} },
Expand All @@ -17,8 +19,24 @@ The FAPI policy supports various features of the Financial-grade API (FAPI) stan
}
]
```
### Log the value of x-fapi-interaction-id header

```
"policy_chain": [
{ "name": "apicast.policy.fapi", "configuration": {} },
{
"name": "apicast.policy.logging",
"configuration": {
"enable_access_logs": false,
"custom_logging": "[{{time_local}}] {{host}}:{{server_port}} {{remote_addr}}:{{remote_port}} x-fapi-interaction-id: {{resp.headers.x-fapi-interaction-id}} \"{{request}}\" {{status}} {{body_bytes_sent}} ({{request_time}}) {{post_action_impact}} ",
}
}
{ "name": "apicast.policy.apicast" }
]
```

### Validate x-fapi-customer-ip-address header
Validate requests with a x-fapi-customer-ip-address header containing a valid IPv4 or IPv6 address

```
"policy_chain": [
Expand All @@ -36,6 +54,13 @@ The FAPI policy supports various features of the Financial-grade API (FAPI) stan

### Validate certificate-bound access tokens

Certificate-bound access tokens, as defined in [RFC 8705]((https://datatracker.ietf.org/doc/html/rfc8705)), enhance security by linking tokens to clients, thereby verifying the sender's authorization to access protected resources.

You'll need to:
* Configure an Identity Provider (IdP) such as Keycloak configured with mTLS and X.509 client certificate authentication.
* Configure the gateway to handle mTLS client certificate authentication.
* Enable `validate_oauth2_certificate_bound_access_token` in the FAPI plugin.

```
"policy_chain": [
{
Expand Down
8 changes: 4 additions & 4 deletions gateway/src/apicast/policy/fapi/fapi.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ local b64 = require('ngx.base64')
local fmt = string.format

local new = _M.new
local X_FAPI_TRANSACTION_ID_HEADER = "x-fapi-transaction-id"
local X_FAPI_INTERACTION_ID_HEADER = "x-fapi-interaction-id"
local X_FAPI_CUSTOMER_IP_ADDRESS = "x-fapi-customer-ip-address"

-- The "x5t#S256" (X.509 Certificate SHA-256 Thumbprint) Header
Expand Down Expand Up @@ -98,15 +98,15 @@ end
function _M:header_filter()
--- 6.2.1.11
-- shall set the response header x-fapi-interaction-id to the value received from the corresponding FAPI client request header or to a RFC4122 UUID value if the request header was not provided to track the interaction
local transaction_id = ngx.req.get_headers()[X_FAPI_TRANSACTION_ID_HEADER]
local transaction_id = ngx.req.get_headers()[X_FAPI_INTERACTION_ID_HEADER]
if not transaction_id or transaction_id == "" then
-- Nothing found, generate one
transaction_id = ngx.resp.get_headers()[X_FAPI_TRANSACTION_ID_HEADER]
transaction_id = ngx.resp.get_headers()[X_FAPI_INTERACTION_ID_HEADER]
if not transaction_id or transaction_id == "" then
transaction_id = uuid.generate_v4()
end
end
ngx.header[X_FAPI_TRANSACTION_ID_HEADER] = transaction_id
ngx.header[X_FAPI_INTERACTION_ID_HEADER] = transaction_id
end

return _M
Loading