Skip to content

Commit

Permalink
feat(jans-cedarling): add krakend plugin (#10713)
Browse files Browse the repository at this point in the history
* feat(jans-cedarling): add krakend plugin

Signed-off-by: SafinWasi <[email protected]>

* docs(jans-cedarling): add krakend plugin readme

Signed-off-by: SafinWasi <[email protected]>

* ci: add workflow to build plugin

Signed-off-by: SafinWasi <[email protected]>

* chore(jans-cedarling): fix module name

Signed-off-by: SafinWasi <[email protected]>

* docs(jans-cedarling): add test instructions

Signed-off-by: SafinWasi <[email protected]>

* ci: remove TTY option

Signed-off-by: moabu <[email protected]>

* ci: remove builder:2.9.0-linux-generic from cedarling krakend

Signed-off-by: moabu <[email protected]>

* ci: add builder:2.9.0-linux-generic from cedarling krakend

Signed-off-by: moabu <[email protected]>

* ci: add builder:2.9.0-linux-generic from cedarling krakend

Signed-off-by: moabu <[email protected]>

* ci: handle CC edge case

Signed-off-by: moabu <[email protected]>

* ci: fix CC var

Signed-off-by: moabu <[email protected]>

* ci: fix CC var

Signed-off-by: moabu <[email protected]>

* docs(jans-cedarling): update readme

Signed-off-by: SafinWasi <[email protected]>

* docs(jans-cedarling): add sequence diagram and steps

Signed-off-by: SafinWasi <[email protected]>

---------

Signed-off-by: SafinWasi <[email protected]>
Signed-off-by: moabu <[email protected]>
Co-authored-by: Mohammad Abudayyeh <[email protected]>
  • Loading branch information
SafinWasi and moabu authored Jan 23, 2025
1 parent bee683b commit 78457b6
Show file tree
Hide file tree
Showing 8 changed files with 572 additions and 1 deletion.
58 changes: 58 additions & 0 deletions .github/workflows/build-packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -438,3 +438,61 @@ jobs:
gpg --armor --detach-sign cedarling_wasm_"${TAG}"_pkg.tar.gz || echo "Failed to sign"
echo "${{ secrets.MOAUTO_WORKFLOW_TOKEN }}" | gh auth login --with-token
gh release upload "${VERSION}" *.tar.gz *.sha256sum *.asc
build_cedarling_krakend:
if: github.repository == 'JanssenProject/jans'
runs-on: ubuntu-20.04
strategy:
matrix:
krakend-builder-image: [ 'builder:2.9.0', 'builder:2.9.0-linux-generic' ]
steps:
- name: Harden Runner
uses: step-security/harden-runner@a4aa98b93cab29d9b1101a6143fb8bce00e2eac4 # v2.7.1
with:
egress-policy: audit

- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Import GPG key
id: import_gpg
continue-on-error: true
uses: crazy-max/ghaction-import-gpg@01dd5d3ca463c7f10f7f4f7b4f177225ac661ee4 # v6.1.0
with:
gpg_private_key: ${{ secrets.MOAUTO_GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.MOAUTO_GPG_PRIVATE_KEY_PASSPHRASE }}
git_user_signingkey: true
git_commit_gpgsign: true
- name: Set environment variables
run: |
TAG=$(echo ${{ github.event.ref }} | cut -d '/' -f 3 | sed 's/^v//')
VERSION="$(echo ${{ github.event.ref }} | cut -d '/' -f 3)"
if [ "${TAG}" == "nightly" ]; then
VERSION=nightly
TAG="0.0.0"
fi
echo TAG=${TAG} >> $GITHUB_ENV
echo VERSION=${VERSION} >> $GITHUB_ENV
KRAKEND_BUILDER_IMAGE=${{ matrix.krakend-builder-image }}
KRAKEND_BUILDER_IMAGE=${KRAKEND_BUILDER_IMAGE/:/-}
echo KRAKEND_BUILDER_IMAGE=${KRAKEND_BUILDER_IMAGE} >> $GITHUB_ENV
echo CC="aarch64-linux-musl-gcc" >> $GITHUB_ENV
if [ "${{ matrix.krakend-builder-image }}" == "builder:2.9.0-linux-generic" ]; then
echo CC="aarch64-linux-gnu-gcc" >> $GITHUB_ENV
fi
- name: Build plugin for AMD64
working-directory: ${{ github.workspace }}/jans-cedarling/cedarling-krakend
run: |
docker run -i -v "$PWD:/app" -w /app krakend/"${{ matrix.krakend-builder-image }}" go build -buildmode=plugin -o cedarling-krakend-amd64-"${{ env.KRAKEND_BUILDER_IMAGE }}"-"${{ env.TAG }}".so .
- name: Build plugin for ARM64
working-directory: ${{ github.workspace }}/jans-cedarling/cedarling-krakend
run: |
docker run -i -v "$PWD:/app" -w /app -e "CGO_ENABLED=1" -e "CC=${{ env.CC }}" -e "GOARCH=arm64" -e "GOHOSTARCH=amd64" krakend/"${{ matrix.krakend-builder-image }}" go build -ldflags='-extldflags=-fuse-ld=bfd -extld=${{ env.CC }}' -buildmode=plugin -o cedarling-krakend-arm64-"${{ env.KRAKEND_BUILDER_IMAGE }}"-"${{ env.TAG }}".so .
- name: Generate sha256sum and sign
working-directory: ${{ github.workspace }}/jans-cedarling/cedarling-krakend
run: |
sha256sum cedarling-krakend-amd64-"${{ env.KRAKEND_BUILDER_IMAGE }}"-"${{ env.TAG }}".so >> cedarling-krakend-amd64-"${{ env.KRAKEND_BUILDER_IMAGE }}"-"${{ env.TAG }}".so.sha256sum
sha256sum cedarling-krakend-arm64-"${{ env.KRAKEND_BUILDER_IMAGE }}"-"${{ env.TAG }}".so >> cedarling-krakend-arm64-"${{ env.KRAKEND_BUILDER_IMAGE }}"-"${{ env.TAG }}".so.sha256sum
gpg --armor --detach-sign cedarling-krakend-amd64-"${{ env.KRAKEND_BUILDER_IMAGE }}"-"${{ env.TAG }}".so || echo "Failed to sign"
gpg --armor --detach-sign cedarling-krakend-arm64-"${{ env.KRAKEND_BUILDER_IMAGE }}"-"${{ env.TAG }}".so || echo "Failed to sign"
echo "${{ secrets.MOAUTO_WORKFLOW_TOKEN }}" | gh auth login --with-token
gh release upload "${{ env.VERSION }}" *.so *.sha256sum *.asc
137 changes: 137 additions & 0 deletions docs/cedarling/cedarling-krakend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
# Cedarling KrakenD Plugin

This is a [KrakenD HTTP server plugin](https://www.krakend.io/docs/extending/http-server-plugins/) that intercepts a call to a selected endpoint, calls the [sidecar](https://github.com/JanssenProject/jans/blob/main/jans-cedarling/flask-sidecar/README.md) and allows access only if the sidecar responds with `true`.

## Functionality

When an end user calls the KrakenD endpoint protected by the plugin, the following steps happen:

1. The plugin intercepts the call, and creates an [AuthZen](https://openid.github.io/authzen/) access evaluation request.
2. The plugin sends the request to the sidecar, which is running on the same host as KrakenD
3. The sidecar calls cedarling's `authz()` interface to check if this call is allowed or not according to the policy store loaded
4. The sidecar responds back to the plugin. If the decision was `true`, the plugin allows the request to pass through to the KrakenD backend. Otherwise, it responds with 403 Forbidden.

[Sequence Diagram](https://sequencediagram.org/index.html#initialData=C4S2BsFMAIGFICYEMBO4QDsDm0DSKkBrSDAEWgAdwBXLTAKACMB7YYZgWwtVAGMRuGYAGdo9etxR8BSIXHQlgEniH6DgeAsTLKpqmXIDKIBJF6pd09XESp02cbAVCAtAD58REqQBc0AOIAogAq0AD0FCisZsCIADoY0C4AEtAARACC1MAAFswoIABeSKDMGH4AQpCokCjQADwAUgDqwW5p9J7apO7GpuYofgDeacLUjABWMWk+I8AAnhSQM2ktwWkANAlpJiu8tmiYWJvbkcxLepDCMyNIvPvCwgD67NorTa3tAL5fWxhpKCuzGoKH2NzSCyWK0asmEPh8yWCwQACk8AEqQACO1CuwBO-12PlGnEgT12GzSZwuoCu4Jy1VMKBuv22IPAdOYwjxRIAjAAmADsADoAAyioU8zaUko5FYRKKxXixBD4ykK5i8Zjsok5NgUNI-Fn-O6lf6zNIYJAcZZEmEYOE+DJKkBleFxNJBYLug1feh9MyodzwZCHbB+JDZHKFAAUdwez1eJAAvB82n9AcJgaDIEmhXm-iaXRhc3mAJT0JDgDTAFA4+jBuxHXomAODaA1uv+gbuLreYZpfogYRFmbt2uQX29shB5zAftnRXKskYABmzFHO1X699kHAwhgK8r+-rB3sWGb-VQfkPe8gfpb3Y8Wj70BGg+HZVHN-3k+f07cTggIofgACwigAzNAABi+SMCYpgYPQJAIEAA)

## Downloading

The cedarling-krakend plugin builds are available via [Janssen](https://github.com/JanssenProject/jans/releases) releases. Please note that builds are architecture, platform, and KrakenD version specific. This means that builds compiled against KrakenD version `2.9.0` will not work on other versions. The build tags are formatted as follows:

```
cedarling-krakend-<architecture>-<krakend version and platform>-<Janssen version>.so
```

Use the following table to find which build you need:

| | amd64 | arm64 |
| - | ----- | ----- |
| Docker | `amd64-builder-2.9.0-0.0.0.so` | `arm64-builder-2.9.0-0.0.0.so` |
| On-premise | `amd64-builder-2.9.0-linux-generic-0.0.0.so` | `arm64-builder-2.9.0-linux-generic-0.0.0.so` |

If you are running a different version of KrakenD, you can use the following steps to build the plugin yourself.

## Building

Krakend recommends building via their builder docker image, to produce builds that match the target architecture and Go version. To build:

- Clone the Janssen repository
```
git clone --filter blob:none --no-checkout https://github.com/JanssenProject/jans
cd jans
git sparse-checkout init --cone
git checkout main
git sparse-checkout set jans-cedarling
cd cedarling-krakend
```
- Build the plugin, replacing `<x.y.z>` with the KrakenD version you want to build against:
- For Docker targets:
```
docker run -it -v "$PWD:/app" -w /app krakend/builder:<x.y.z> go build -buildmode=plugin -o cedarling-krakend.so .
```
- For on-premise installations:
```
docker run -it -v "$PWD:/app" -w /app krakend/builder:<x.y.z>-linux-generic go build -buildmode=plugin -o yourplugin.so .
```
- For ARM64 Docker targets:
```bash
docker run -it -v "$PWD:/app" -w /app \
-e "CGO_ENABLED=1" \
-e "CC=aarch64-linux-musl-gcc" \
-e "GOARCH=arm64" \
-e "GOHOSTARCH=amd64" \
krakend/builder:<x.y.z> \
go build -ldflags='-extldflags=-fuse-ld=bfd -extld=aarch64-linux-musl-gcc' \
-buildmode=plugin -o yourplugin.so .
```
- For ARM64 on-premise installs:
```bash
docker run -it -v "$PWD:/app" -w /app \
-e "CGO_ENABLED=1" \
-e "CC=aarch64-linux-gnu-gcc" \
-e "GOARCH=arm64" \
-e "GOHOSTARCH=amd64" \
krakend/builder:<x.y.z>-linux-generic \
go build -ldflags='-extldflags=-fuse-ld=bfd -extld=aarch64-linux-gnu-gcc' \
-buildmode=plugin -o yourplugin.so .
```
Check [KrakenD documentation](https://www.krakend.io/docs/extending/injecting-plugins/) on how to load plugins.
## Prerequisites for testing
To test the plugin, you will need:
- A cedarling policy store with a policy for our gateway. To create this, please follow [these](https://github.com/JanssenProject/jans/wiki/Cedarling-Hello-World-%5BWIP%5D#setup-policy-store) steps.
- An instance of the cedarling sidecar, using the policy store mentioned above. Please follow [these](https://github.com/JanssenProject/jans/wiki/Cedarling-Hello-World-%5BWIP%5D#setup-sidecar) steps.
- For our demo, we will use this sample policy as outlined in the instructions:
```
@id("allow_one")
permit(
principal is gatewayDemo::Workload,
action == gatewayDemo::Action::"GET",
resource is gatewayDemo::HTTP_Request
)
when {
(principal["client_id"]) == "d7f71bea-c38d-4caf-a1ba-e43c74a11a62"
};
```
- A [KrakenD server installation](https://www.krakend.io/docs/overview/installing/). For development purposes, the binary install is recommended. For production setups, the Docker method is recommended.
- The plugin `.so` file for your architecture. For Mac OS hosts, ARM64 is required.
- A configuration file. Sample configuration is provided in [krakend.json](https://github.com/JanssenProject/jans/blob/main/jans-cedarling/cedarling-krakend/krakend.json).
## Configuration
See [krakend.json](https://github.com/JanssenProject/jans/blob/main/jans-cedarling/cedarling-krakend/krakend.json) to see an example KrakenD configuration which loads the plugin. The following table describes the plugin-specific configuration keys. These keys are mandatory and must be provided. Additional configuration is described in [KrakenD documentation](https://www.krakend.io/docs/configuration/structure/).
The `namespace` field in the configuration needs to be the cedar namespace you used when creating the policy store. By default, Agama Lab sets the namespace to the name of the policy store. If you are following the demo, this value is `gatewayDemo`.
| Field | Type | Example | Description |
|-------|------|---------|-------------|
| path | String | /protected | KrakenD endpoint to protect |
| sidecar_endpoint | String | http://127.0.0.1:5000/cedarling/evaluation | Sidecar evaluation URL |
| namespace | String | gatewayDemo | Cedar namespace being used by the sidecar |
## Running
1. Start the cedarling sidecar. The sample config expects the sidecar to be running on port 5000
2. Place `krakend.json` and the plugin `.so` file in your current working directory
2. Run the KrakenD server: `krakend run -c krakend.json`
3. KrakenD is running on `http://127.0.0.1:8080`
4. Test with no authentication: `curl http://127.0.0.1:8080/protected`. You should get a 403 Forbidden
5. Test with authentication:
```bash
ACCESS_TOKEN=eyJraWQiOiJjb25uZWN0X2Y5YTAwN2EyLTZkMGItNDkyYS05MGNkLWYwYzliMWMyYjVkYl9zaWdfcnMyNTYiLCJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJxenhuMVNjcmI5bFd0R3hWZWRNQ2t5LVFsX0lMc3BaYVFBNmZ5dVlrdHcwIiwiY29kZSI6IjNlMmEyMDEyLTA5OWMtNDY0Zi04OTBiLTQ0ODE2MGMyYWIyNSIsImlzcyI6Imh0dHBzOi8vYWNjb3VudC5nbHV1Lm9yZyIsInRva2VuX3R5cGUiOiJCZWFyZXIiLCJjbGllbnRfaWQiOiJkN2Y3MWJlYS1jMzhkLTRjYWYtYTFiYS1lNDNjNzRhMTFhNjIiLCJhdWQiOiJkN2Y3MWJlYS1jMzhkLTRjYWYtYTFiYS1lNDNjNzRhMTFhNjIiLCJhY3IiOiJzaW1wbGVfcGFzc3dvcmRfYXV0aCIsIng1dCNTMjU2IjoiIiwibmJmIjoxNzMxOTUzMDMwLCJzY29wZSI6WyJyb2xlIiwib3BlbmlkIiwicHJvZmlsZSIsImVtYWlsIl0sImF1dGhfdGltZSI6MTczMTk1MzAyNywiZXhwIjoxNzMyMTIxNDYwLCJpYXQiOjE3MzE5NTMwMzAsImp0aSI6InVaVWgxaERVUW82UEZrQlBud3BHemciLCJ1c2VybmFtZSI6IkRlZmF1bHQgQWRtaW4gVXNlciIsInN0YXR1cyI6eyJzdGF0dXNfbGlzdCI6eyJpZHgiOjMwNiwidXJpIjoiaHR0cHM6Ly9qYW5zLnRlc3QvamFucy1hdXRoL3Jlc3R2MS9zdGF0dXNfbGlzdCJ9fX0.Pt-Y7F-hfde_WP7ZYwyvvSS11rKYQWGZXTzjH_aJKC5VPxzOjAXqI3Igr6gJLsP1aOd9WJvOPchflZYArctopXMWClbX_TxpmADqyCMsz78r4P450TaMKj-WKEa9cL5KtgnFa0fmhZ1ZWolkDTQ_M00Xr4EIvv4zf-92Wu5fOrdjmsIGFot0jt-12WxQlJFfs5qVZ9P-cDjxvQSrO1wbyKfHQ_txkl1GDATXsw5SIpC5wct92vjAVm5CJNuv_PE8dHAY-KfPTxOuDYBuWI5uA2Yjd1WUFyicbJgcmYzUSVt03xZ0kQX9dxKExwU2YnpDorfwebaAPO7G114Bkw208g
curl http://127.0.0.1:8080/protected -H "Authorization: Bearer $ACCESS_TOKEN"
```

KrakenD is configured to respond with the health check response if authentication succeeds.
Loading

0 comments on commit 78457b6

Please sign in to comment.