-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add code * Remove replace * Configure private modules * Configure private modules * Use netrc * Fix docker * Fix docker * Fix docker * Fix goreleaser
- Loading branch information
Showing
17 changed files
with
2,786 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
--- | ||
name: Release | ||
on: | ||
push: | ||
tags: | ||
- v* | ||
jobs: | ||
releaseBinaries: | ||
name: Release Binaries | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Install Go | ||
uses: actions/setup-go@v2 | ||
with: | ||
go-version: 1.16.x | ||
|
||
- name: Checkout code | ||
uses: actions/checkout@v2 | ||
with: | ||
fetch-depth: 0 | ||
|
||
- name: Set up QEMU | ||
id: qemu | ||
uses: docker/setup-qemu-action@v1 | ||
with: | ||
image: tonistiigi/binfmt:latest | ||
platforms: arm64 | ||
|
||
- name: Set up Docker Buildx | ||
id: buildx | ||
uses: docker/setup-buildx-action@v1 | ||
|
||
- name: Configure Git for private modules | ||
run: echo "machine github.com login ${{ secrets.PRIVATE_REPO_CHECKOUT_TOKEN }} password x-oauth-basic" > $HOME/.netrc | ||
|
||
- name: Login to GHCR | ||
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin | ||
|
||
- name: Login to Artifactory | ||
run: echo "${{ secrets.ARTIFACTORY_PROD_SECRET }}" | docker login cerbos.jfrog.io -u ${{ secrets.ARTIFACTORY_PROD_USERNAME }} --password-stdin | ||
|
||
- uses: actions/cache@v2 | ||
with: | ||
path: | | ||
~/go/pkg/mod | ||
~/.cache/go-build | ||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} | ||
restore-keys: | | ||
${{ runner.os }}-go- | ||
- name: GoReleaser | ||
uses: goreleaser/goreleaser-action@v2 | ||
with: | ||
version: latest | ||
args: release --config=.goreleaser.yml --rm-dist | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
ARTIFACTORY_PROD_USERNAME: ${{ secrets.ARTIFACTORY_PROD_USERNAME }} | ||
ARTIFACTORY_PROD_SECRET: ${{ secrets.ARTIFACTORY_PROD_SECRET }} | ||
DOCKER_BUILDKIT: 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
project_name: demo-rest | ||
builds: | ||
- env: | ||
- CGO_ENABLED=0 | ||
- GOPRIVATE=github.com/cerbos/* | ||
goos: | ||
- linux | ||
- darwin | ||
goarch: | ||
- amd64 | ||
- arm64 | ||
archives: | ||
- replacements: | ||
darwin: Darwin | ||
linux: Linux | ||
amd64: x86_64 | ||
dockers: | ||
- image_templates: | ||
- "ghcr.io/cerbos/demo-rest:{{ .Version }}-amd64" | ||
- "cerbos.jfrog.io/containers/demo-rest:{{ .Version }}-amd64" | ||
goarch: amd64 | ||
use_buildx: true | ||
build_flag_templates: | ||
- "--platform=linux/amd64" | ||
|
||
- image_templates: | ||
- "ghcr.io/cerbos/demo-rest:{{ .Version }}-arm64" | ||
- "cerbos.jfrog.io/containers/demo-rest:{{ .Version }}-arm64" | ||
goarch: arm64 | ||
use_buildx: true | ||
build_flag_templates: | ||
- "--platform=linux/arm64" | ||
docker_manifests: | ||
- name_template: "ghcr.io/cerbos/demo-rest:{{ .Version }}" | ||
image_templates: | ||
- "ghcr.io/cerbos/demo-rest:{{ .Version }}-amd64" | ||
- "ghcr.io/cerbos/demo-rest:{{ .Version }}-arm64" | ||
- name_template: "cerbos.jfrog.io/containers/demo-rest:{{ .Version }}" | ||
image_templates: | ||
- "cerbos.jfrog.io/containers/demo-rest:{{ .Version }}-amd64" | ||
- "cerbos.jfrog.io/containers/demo-rest:{{ .Version }}-arm64" | ||
checksum: | ||
disable: true | ||
changelog: | ||
skip: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
FROM gcr.io/distroless/base | ||
EXPOSE 9999 | ||
ENTRYPOINT ["/demo-rest"] | ||
COPY demo-rest / | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
.PHONY: build | ||
build: | ||
@ goreleaser --config=.goreleaser.yml --snapshot --skip-publish --rm-dist |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,237 @@ | ||
Securing a REST API with Cerbos | ||
=============================== | ||
|
||
This project demonstrates how to secure a REST API using Cerbos policies. It also shows how to run Cerbos as a sidecar. | ||
|
||
|
||
The Store API | ||
------------- | ||
|
||
The example application is a simple REST API exposed by a fictional e-commmerce service. Only authenticated users can access the API. | ||
|
||
| Endpoint | Description | Rules | | ||
| -------- | ----------- | ------------ | | ||
| `PUT /store/order` | Create a new order | Only customers can create orders. Each order must contain at least two items. | | ||
| `GET /store/order/{orderID}` | View the order | Customers can only view their own orders. Store employees can view any order. | | ||
| `POST /store/order/{orderID}` | Update the order | Customers can update their own orders as long as the status is `PENDING` | | ||
| `DELETE /store/order/{orderID}` | Cancel the order | Customers can cancel their own orders as long the status is `PENDING` | | ||
| `POST /backoffice/order/{orderID}/status/{status}` | Update order status | Pickers can change status from `PENDING` to `PICKING` and `PICKING` to `PICKED`. Dispatchers can change status from `PICKED` to `DISPATCHED`. Managers can change the status to anything. | | ||
|
||
|
||
The users are: | ||
|
||
| Username | Password | Roles | | ||
| -------- | -------- | ----- | | ||
| adam | adamsStrongPassword | customer | | ||
| bella | bellasStrongPassword | customer, employee, manager | | ||
| charlie | charliesStrongPassword | customer, employee, picker | | ||
| diana | dianasStrongPassword | customer, employee, dispatcher | | ||
| eve | evesStrongPassword | customer | ||
|
||
|
||
The Cerbos policies for the service are in the `cerbos/policies` directory. | ||
|
||
- `store_roles.yaml`: A derived roles definition which defines `order-owner` derived role to identify when someone is accessing their own order. | ||
- `order_resource.yaml`: A resource policy for the `order` resource encapsulating the rules listed in the first table above. | ||
|
||
|
||
Use `docker-compose` to start the demo. Here Cerbos is configured to run as a sidecar to the application and communicate over a Unix domain socket. | ||
|
||
```sh | ||
docker-compose up | ||
``` | ||
|
||
Examples | ||
-------- | ||
|
||
<details> | ||
<summary><b>Adam tries to create an order with a single item -- which is not allowed by the policy</b></summary> | ||
|
||
|
||
```sh | ||
curl -i -XPUT localhost:9999/store/order -u adam:adamsStrongPassword -d '{"items": {"eggs": 12}}' | ||
``` | ||
|
||
``` | ||
HTTP/1.1 403 Forbidden | ||
Content-Type: application/json | ||
{ | ||
"message": "Operation not allowed" | ||
} | ||
``` | ||
|
||
</details> | ||
|
||
|
||
<details> | ||
<summary><b>Adam now has enough items in his order</b></summary> | ||
|
||
```sh | ||
curl -i -XPUT localhost:9999/store/order -u adam:adamsStrongPassword -d '{"items": {"eggs": 12, "milk": 1}}' | ||
``` | ||
|
||
``` | ||
HTTP/1.1 201 Created | ||
Content-Type: application/json | ||
{ | ||
"orderID": 2 | ||
} | ||
``` | ||
|
||
</details> | ||
|
||
|
||
<details> | ||
<summary><b>Adam can view his own order</b></summary> | ||
|
||
```sh | ||
curl -i -XGET localhost:9999/store/order/2 -u adam:adamsStrongPassword | ||
``` | ||
|
||
``` | ||
HTTP/1.1 200 OK | ||
Content-Type: application/json | ||
{ | ||
"id": 2, | ||
"items": { | ||
"eggs": 12, | ||
"milk": 1 | ||
}, | ||
"owner": "adam", | ||
"status": "PENDING" | ||
} | ||
``` | ||
|
||
</details> | ||
|
||
|
||
<details> | ||
<summary><b>Eve cannot view Adam’s order</b></summary> | ||
|
||
```sh | ||
curl -i -XGET localhost:9999/store/order/2 -u eve:evesStrongPassword | ||
``` | ||
|
||
``` | ||
HTTP/1.1 403 Forbidden | ||
Content-Type: application/json | ||
{ | ||
"message": "Operation not allowed" | ||
} | ||
``` | ||
|
||
</details> | ||
|
||
|
||
<details> | ||
<summary><b>Bella can view Adam’s order because she is an employee</b></summary> | ||
|
||
```sh | ||
curl -i -XGET localhost:9999/store/order/2 -u bella:bellasStrongPassword | ||
``` | ||
|
||
``` | ||
HTTP/1.1 200 OK | ||
Content-Type: application/json | ||
{ | ||
"id": 2, | ||
"items": { | ||
"eggs": 12, | ||
"milk": 1 | ||
}, | ||
"owner": "adam", | ||
"status": "PENDING" | ||
} | ||
``` | ||
|
||
</details> | ||
|
||
|
||
<details> | ||
<summary><b>Adam can update his order because it is still PENDING</b></summary> | ||
|
||
```sh | ||
curl -i -XPOST localhost:9999/store/order/2 -u adam:adamsStrongPassword -d '{"items": {"eggs": 24, "milk": 1, "bread": 1}}' | ||
``` | ||
|
||
``` | ||
HTTP/1.1 200 OK | ||
``` | ||
|
||
</details> | ||
|
||
|
||
<details> | ||
<summary><b>Charlie accidentally tries to set order status to PICKED instead of PICKING</b></summary> | ||
|
||
```sh | ||
curl -i -XPOST localhost:9999/backoffice/order/2/status/PICKED -u charlie:charliesStrongPassword | ||
``` | ||
|
||
``` | ||
HTTP/1.1 403 Forbidden | ||
Content-Type: application/json | ||
{ | ||
"message": "Operation not allowed" | ||
} | ||
``` | ||
|
||
</details> | ||
|
||
|
||
<details> | ||
<summary><b>Charlie starts picking the order</b></summary> | ||
|
||
```sh | ||
curl -i -XPOST localhost:9999/backoffice/order/2/status/PICKING -u charlie:charliesStrongPassword | ||
``` | ||
|
||
``` | ||
HTTP/1.1 200 OK | ||
``` | ||
|
||
</details> | ||
|
||
|
||
<details> | ||
<summary><b>Adam can no longer edit his order because the status has changed</b></summary> | ||
|
||
```sh | ||
curl -i -XDELETE localhost:9999/store/order/2 -u adam:adamsStrongPassword | ||
``` | ||
|
||
``` | ||
HTTP/1.1 403 Forbidden | ||
Content-Type: application/json | ||
{ | ||
"message": "Operation not allowed" | ||
} | ||
``` | ||
|
||
</details> | ||
|
||
|
||
<details> | ||
<summary><b>Diana cannot dispatch the order because the status is still PICKING</b></summary> | ||
|
||
```sh | ||
curl -i -XPOST localhost:9999/backoffice/order/2/status/DISPATCHED -u diana:dianasStrongPassword | ||
``` | ||
|
||
``` | ||
HTTP/1.1 403 Forbidden | ||
Content-Type: application/json | ||
{ | ||
"message": "Operation not allowed" | ||
} | ||
``` | ||
|
||
</details> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
--- | ||
server: | ||
grpcListenAddr: "unix:/sock/cerbos-grpc.sock" | ||
httpListenAddr: "unix:/sock/cerbos-http.sock" | ||
storage: | ||
driver: disk | ||
disk: | ||
directory: /data/policies | ||
watchForChanges: true |
Oops, something went wrong.