Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
353c8f3
fix: initial revision APL.
terylt May 17, 2026
6979aed
feat: apl-cpex bridge crate + plugin-registry-driven hook dispatch
terylt May 17, 2026
9bcfc23
feat: add support for plugin calling in APL routes.
terylt May 17, 2026
0847d57
feat: add more APL plugin support, unified config
terylt May 18, 2026
63aa589
feat: added cedar direct PDP.
terylt May 19, 2026
b0ee6e1
feat: add identity hook and extensions.
terylt May 21, 2026
912c492
feat: added token delegation hooks and tests.
terylt May 21, 2026
3d753d4
feat: added plugin for jwt token identity, oauth and biscuit delegati…
terylt May 22, 2026
a7b3721
fix: updated identity and delegation to support keycloak. added deleg…
terylt May 30, 2026
d6328dc
fix: added some sample plugins, added updates to support cedar.
terylt Jun 1, 2026
ff8c5bd
feat: added session support, serialize and parallel and full effects …
terylt Jun 3, 2026
de29b27
feat: add ffi pre-built .a library
araujof Jun 3, 2026
6b369b2
chore: add workflow_dispatch target
araujof Jun 3, 2026
ec8ddb7
fix: critical and high issues from review.
terylt Jun 3, 2026
5b67a07
feat: add APL FFI and go bindings
araujof Jun 3, 2026
29912b1
chore: add musl tools to musl runners
araujof Jun 3, 2026
d02ee47
merge: merging prebuilt cpexlib_ffi.a into APL branch.
terylt Jun 3, 2026
7d7cc6c
fix: potential double free after use bug.
terylt Jun 3, 2026
8fd9c66
chore: update Go module paths after repo rename to cpex
terylt Jun 4, 2026
df4300e
feat: map identity extension into cpex ffi
araujof Jun 5, 2026
522c1d8
feat: add cpex_invoke_resolved abi
araujof Jun 5, 2026
66b2fc7
fix: has_hook_for handling
araujof Jun 5, 2026
0ffced4
chore: update headers
araujof Jun 5, 2026
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
190 changes: 190 additions & 0 deletions .github/workflows/release-ffi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
# ===============================================================
# Release FFI - Build, sign, and publish libcpex_ffi.a artifacts
# ===============================================================
#
# Triggered by semver-strict tag pushes. Matrix-builds the FFI
# static library for the supported target tuples, packages each into
# a tarball with VERSION / FFI_ABI / LICENSE metadata, signs every
# tarball + the aggregate SHA256SUMS with cosign keyless (Sigstore),
# and attaches everything to the GitHub Release for the tag.
#
# See crates/cpex-ffi/RELEASE.md for the artifact schema and the
# consumer-side verify-and-unpack recipe.

name: Release FFI

on:
push:
tags:
# Semver-strict. Two patterns so vMAJOR.MINOR.PATCH (release)
# and vMAJOR.MINOR.PATCH-<prerelease> (rc / beta / ffi.test)
# both fire, while loose `v*` matches (vendor-bump, v1, v-foo)
# and the legacy non-prefixed tags (0.1.0, plugins.dev1) do not.
# Dry-run tags like v0.0.0-ffi.test.1 deliberately hit the
# prerelease branch.
- 'v[0-9]+.[0-9]+.[0-9]+'
- 'v[0-9]+.[0-9]+.[0-9]+-*'
workflow_dispatch:

# id-token: write is what unlocks Sigstore keyless signing (Fulcio
# reads the GHA OIDC token to issue the short-lived signing cert).
# contents: write is needed to create / upload to the GitHub Release.
permissions:
contents: write
id-token: write

# Prevent concurrent runs on the same tag from racing the release
# creation. Tag pushes are one-shot, so this is belt-and-suspenders.
concurrency:
group: release-ffi-${{ github.ref }}
cancel-in-progress: false

jobs:
build:
name: Build ${{ matrix.target }}
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false # one tuple failing should not cancel the others
matrix:
include:
- target: x86_64-unknown-linux-gnu
runner: ubuntu-latest
- target: aarch64-unknown-linux-gnu
runner: ubuntu-22.04-arm
- target: x86_64-unknown-linux-musl
runner: ubuntu-latest
- target: aarch64-unknown-linux-musl
runner: ubuntu-22.04-arm
- target: aarch64-apple-darwin
runner: macos-14

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Install Rust toolchain
# dtolnay/rust-toolchain is the de-facto rustup action.
# `stable` picks the latest stable; pin if we need a floor.
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}

- name: Cache cargo build
uses: Swatinem/rust-cache@v2
with:
# Share cache across tags (the key includes the target +
# Cargo.lock hash by default). Significant speedup on
# subsequent releases of the same target.
key: ${{ matrix.target }}

- name: Install musl toolchain
# ring (via jsonwebtoken/rustls/quinn) compiles C + asm through
# cc-rs, which for a *-unknown-linux-musl target shells out to
# <arch>-linux-musl-gcc. The runners ship only the glibc gcc, so
# we install musl-gcc here. The matrix runs each musl target on
# its native-arch runner, so musl-gcc targets the host arch and
# the CC_/LINKER env vars below redirect cc-rs and the linker to
# it. Scoped to the musl legs; gnu/darwin use their default cc.
if: contains(matrix.target, 'musl')
run: sudo apt-get update && sudo apt-get install -y musl-tools musl-dev

- name: Build artifact
env:
TARGET: ${{ matrix.target }}
# VERSION drops the leading "refs/tags/" so the tarball
# name matches the tag verbatim.
VERSION: ${{ github.ref_name }}
DIST_DIR: dist
# Point cc-rs and the linker at musl-gcc for the musl targets.
# No-ops for gnu/darwin (those triples don't match these keys).
CC_x86_64_unknown_linux_musl: musl-gcc
CC_aarch64_unknown_linux_musl: musl-gcc
CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER: musl-gcc
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER: musl-gcc
run: bash scripts/release/build-artifact.sh

- name: Upload tarball + sha256
uses: actions/upload-artifact@v4
with:
# Unique per-target name so the download step in
# sign-and-release can merge them all into one dist/.
name: cpex-ffi-${{ github.ref_name }}-${{ matrix.target }}
path: dist/cpex-ffi-*
if-no-files-found: error
retention-days: 7

sign-and-release:
name: Sign and publish release
needs: [build]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Download all matrix artifacts
uses: actions/download-artifact@v4
with:
path: dist
# merge-multiple flattens the per-target subdirs into one
# dist/ so the sign script and gh release upload see a
# flat layout.
merge-multiple: true

- name: Generate aggregate SHA256SUMS
env:
VERSION: ${{ github.ref_name }}
run: |
set -euo pipefail
cd dist
# Concat all individual .sha256 files into one signed
# integrity manifest. The per-tarball .sha256 files stay
# as convenience companions, but the SHA256SUMS file is
# what auditors care about.
: > "cpex-ffi-${VERSION}-SHA256SUMS"
for f in cpex-ffi-*.tar.gz; do
if command -v sha256sum >/dev/null; then
sha256sum "$f" >> "cpex-ffi-${VERSION}-SHA256SUMS"
else
shasum -a 256 "$f" >> "cpex-ffi-${VERSION}-SHA256SUMS"
fi
done
echo "--- SHA256SUMS ---"
cat "cpex-ffi-${VERSION}-SHA256SUMS"

- name: Install cosign
uses: sigstore/cosign-installer@v3

- name: Sign artifacts
env:
DIST_DIR: dist
run: bash scripts/release/sign-artifact.sh

- name: Create or update GitHub Release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ github.ref_name }}
run: |
set -euo pipefail

# Auto-detect prerelease by suffix so dry-run tags
# (v0.0.0-ffi.test.1) land as prereleases and don't surface
# as "latest" on the repo's Releases page.
PRERELEASE_FLAG=""
if [[ "$TAG" == *-* ]]; then
PRERELEASE_FLAG="--prerelease"
fi

# Idempotent: if the release exists, upload --clobber the
# new files; if it doesn't, create it with the tarballs +
# SHA256SUMS + sigs in one shot.
if gh release view "$TAG" >/dev/null 2>&1; then
echo "Release $TAG exists; uploading artifacts with --clobber"
gh release upload "$TAG" dist/cpex-ffi-* --clobber
else
echo "Creating release $TAG"
gh release create "$TAG" \
--title "$TAG" \
--notes "Automated FFI artifact release. See crates/cpex-ffi/RELEASE.md for the schema and verify-and-consume recipe." \
$PRERELEASE_FLAG \
dist/cpex-ffi-*
fi
19 changes: 18 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ FIXMEs
logs/
*.log
.sketchpad
.localtarget*

# Fuzzing artifacts and reports
reports/
Expand Down Expand Up @@ -194,13 +195,29 @@ celerybeat-schedule

# Environments
.env
.env.*
*.env
env.bak/
env.back
env.bak
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Loose credential / token files — defensive net against accidental
# `git add` of dev-captured real tokens. The `.env` patterns above
# already cover the canonical case.
bearertoken*
*.token
*.tokens
*credentials*.json
*credentials*.yaml
*credentials*.yml
apikey*
*.pem

# Spyder project settings
.spyderproject
.spyproject
Expand Down
30 changes: 30 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,36 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).

## [Unreleased]

### Added

- APL (Attribute Policy Language) governance is now bundled into
`libcpex_ffi.a`. New `cpex_apl_install` extern C entry point registers
the standard APL plugin/PDP factories (`validator/pii-scan`,
`audit/logger`, `identity/jwt`, `delegator/oauth`, `cedar-direct`) and
installs the APL config visitor on a manager. Call it after
`cpex_manager_new_default` and before `cpex_load_config`. Go hosts use
`PluginManager.EnableAPL()`. The optional `cedarling` cargo feature adds
the Cedarling-backed identity + PDP seams (off by default; the released
`.a` stays lean).
- Publish `libcpex_ffi.a` as signed GitHub Release artifacts on
every semver tag push (`linux-amd64-gnu`, `linux-arm64-gnu`,
`linux-amd64-musl`, `linux-arm64-musl`, `darwin-arm64`). Cosign
keyless signatures + SHA256 checksums; see
`crates/cpex-ffi/RELEASE.md` for the schema and the verify-and-
consume recipe.
- FFI ABI versioning: `cpex_ffi_abi_version()` extern C accessor
exposes `FFI_ABI_VERSION`. The Go binding checks this in `init()`
and panics on mismatch. Other language bindings must replicate the
check.

### Changed

- FFI `FFI_ABI_VERSION` bumped `1 → 2`: added the `cpex_apl_install`
extern C function and changed `cpex_load_config` to run registered
config visitors (it now calls `load_config_yaml` internally so `apl:`
blocks are walked). The Go binding's `expectedFFIABIVersion` is bumped
in lockstep.

## [0.1.0] - 2026-05-05

### Added
Expand Down
Loading
Loading