From bcb6dbee654c3919ae5dac352b889c4503335b0a Mon Sep 17 00:00:00 2001 From: Michael Neil Date: Tue, 27 Oct 2020 19:59:09 -0700 Subject: [PATCH 01/11] Initialize docs with docsify Added a make command to run docsify. --- Makefile | 4 ++++ docs/.nojekyll | 0 docs/README.md | 24 ++++++++++++++++++++++++ docs/index.html | 21 +++++++++++++++++++++ 4 files changed, 49 insertions(+) create mode 100644 docs/.nojekyll create mode 100644 docs/README.md create mode 100644 docs/index.html diff --git a/Makefile b/Makefile index 85e1157..cd74303 100644 --- a/Makefile +++ b/Makefile @@ -8,6 +8,10 @@ run: --authorization=basic \ --set=services.opa.credentials=null +serve-docs: + # Requires nodejs and docsify + docsify serve ./docs + unit: go test -v -short ./... diff --git a/docs/.nojekyll b/docs/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..edc290a --- /dev/null +++ b/docs/README.md @@ -0,0 +1,24 @@ +# OPA DynamoDB + +Infinitely scalable policy store with instantaneous policy updates for use by small and enterprise scale teams wanting to use Open Policy Agent. + +OPA DynamoDB adds custom functionality to rego policies to query data from DynamoDB. + +OPA has several strategies for managing policies at scale and accepting internal data which you can [read about here](https://www.openpolicyagent.org/docs/latest/external-data/). This repository implements [Option 5](https://www.openpolicyagent.org/docs/latest/external-data/#option-5-pull-data-during-evaluation) using DynamoDB as the external data source. This implementation also removes the current limitations described by OPA. + + - Using this runtime you can test your policies against external data + - AWS credentials can be infered by the credentials chain in Goland AWS SDK + - Retry logic and caching are implemented by the AWS SDK and this implementation + +## DynamoDB As A Backend + +DynamoDB is an excellent backend for policy data. You can store documentesque data across dynamo rows and query them using a collections pattern. This method is efficient (single read to get entire policy) and scalable (dynamodb storage is extremely scalable). + +If you want to understand more about Single Table Design, item collections, and DynamoDB in general I recommend this book by Alex Debrie https://www.dynamodbbook.com/. I have no affiliation with Alex or his book. It's that good. + +## Architecture + +This high level flow diagram shows how we can check if a user attempting to get a document has access to this document or not. + +[![](https://mermaid.ink/img/eyJjb2RlIjoiZ3JhcGggVERcbiAgICBcbiAgICBVc2VyKChVc2VyKSkgLS0-IHxSZWFkIERvY3VtZW50fCBBcHBsaWNhdGlvblxuICAgIEFwcGxpY2F0aW9uIC0tPiB8Q2FuIFVzZXIgUmVhZHwgT1BBe0V2YWx1YXRlIFBvbGljeX1cbiAgICBPUEEgLS0-IHxHZXQgUG9saWN5fCBEeW5hbW9bKER5bmFtbyldXG4gICAgRHluYW1vIC0tPiBPUEFcbiAgICBPUEEgLS0-fFJlc3VsdHwgQXBwbGljYXRpb25cbiAgICBBcHBsaWNhdGlvbiAtLT4gfEFsbG93OiBSZXR1cm4gRG9jdW1lbnR8IFVzZXJcbiAgICBBcHBsaWNhdGlvbiAtLT4gfERlbnl8IEVycm9yXG4gICAgICAgICAgICAiLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCIsInRoZW1lVmFyaWFibGVzIjp7ImJhY2tncm91bmQiOiJ3aGl0ZSIsInByaW1hcnlDb2xvciI6IiNFQ0VDRkYiLCJzZWNvbmRhcnlDb2xvciI6IiNmZmZmZGUiLCJ0ZXJ0aWFyeUNvbG9yIjoiaHNsKDgwLCAxMDAlLCA5Ni4yNzQ1MDk4MDM5JSkiLCJwcmltYXJ5Qm9yZGVyQ29sb3IiOiJoc2woMjQwLCA2MCUsIDg2LjI3NDUwOTgwMzklKSIsInNlY29uZGFyeUJvcmRlckNvbG9yIjoiaHNsKDYwLCA2MCUsIDgzLjUyOTQxMTc2NDclKSIsInRlcnRpYXJ5Qm9yZGVyQ29sb3IiOiJoc2woODAsIDYwJSwgODYuMjc0NTA5ODAzOSUpIiwicHJpbWFyeVRleHRDb2xvciI6IiMxMzEzMDAiLCJzZWNvbmRhcnlUZXh0Q29sb3IiOiIjMDAwMDIxIiwidGVydGlhcnlUZXh0Q29sb3IiOiJyZ2IoOS41MDAwMDAwMDAxLCA5LjUwMDAwMDAwMDEsIDkuNTAwMDAwMDAwMSkiLCJsaW5lQ29sb3IiOiIjMzMzMzMzIiwidGV4dENvbG9yIjoiIzMzMyIsIm1haW5Ca2ciOiIjRUNFQ0ZGIiwic2Vjb25kQmtnIjoiI2ZmZmZkZSIsImJvcmRlcjEiOiIjOTM3MERCIiwiYm9yZGVyMiI6IiNhYWFhMzMiLCJhcnJvd2hlYWRDb2xvciI6IiMzMzMzMzMiLCJmb250RmFtaWx5IjoiXCJ0cmVidWNoZXQgbXNcIiwgdmVyZGFuYSwgYXJpYWwiLCJmb250U2l6ZSI6IjE2cHgiLCJsYWJlbEJhY2tncm91bmQiOiIjZThlOGU4Iiwibm9kZUJrZyI6IiNFQ0VDRkYiLCJub2RlQm9yZGVyIjoiIzkzNzBEQiIsImNsdXN0ZXJCa2ciOiIjZmZmZmRlIiwiY2x1c3RlckJvcmRlciI6IiNhYWFhMzMiLCJkZWZhdWx0TGlua0NvbG9yIjoiIzMzMzMzMyIsInRpdGxlQ29sb3IiOiIjMzMzIiwiZWRnZUxhYmVsQmFja2dyb3VuZCI6IiNlOGU4ZTgiLCJhY3RvckJvcmRlciI6ImhzbCgyNTkuNjI2MTY4MjI0MywgNTkuNzc2NTM2MzEyOCUsIDg3LjkwMTk2MDc4NDMlKSIsImFjdG9yQmtnIjoiI0VDRUNGRiIsImFjdG9yVGV4dENvbG9yIjoiYmxhY2siLCJhY3RvckxpbmVDb2xvciI6ImdyZXkiLCJzaWduYWxDb2xvciI6IiMzMzMiLCJzaWduYWxUZXh0Q29sb3IiOiIjMzMzIiwibGFiZWxCb3hCa2dDb2xvciI6IiNFQ0VDRkYiLCJsYWJlbEJveEJvcmRlckNvbG9yIjoiaHNsKDI1OS42MjYxNjgyMjQzLCA1OS43NzY1MzYzMTI4JSwgODcuOTAxOTYwNzg0MyUpIiwibGFiZWxUZXh0Q29sb3IiOiJibGFjayIsImxvb3BUZXh0Q29sb3IiOiJibGFjayIsIm5vdGVCb3JkZXJDb2xvciI6IiNhYWFhMzMiLCJub3RlQmtnQ29sb3IiOiIjZmZmNWFkIiwibm90ZVRleHRDb2xvciI6ImJsYWNrIiwiYWN0aXZhdGlvbkJvcmRlckNvbG9yIjoiIzY2NiIsImFjdGl2YXRpb25Ca2dDb2xvciI6IiNmNGY0ZjQiLCJzZXF1ZW5jZU51bWJlckNvbG9yIjoid2hpdGUiLCJzZWN0aW9uQmtnQ29sb3IiOiJyZ2JhKDEwMiwgMTAyLCAyNTUsIDAuNDkpIiwiYWx0U2VjdGlvbkJrZ0NvbG9yIjoid2hpdGUiLCJzZWN0aW9uQmtnQ29sb3IyIjoiI2ZmZjQwMCIsInRhc2tCb3JkZXJDb2xvciI6IiM1MzRmYmMiLCJ0YXNrQmtnQ29sb3IiOiIjOGE5MGRkIiwidGFza1RleHRMaWdodENvbG9yIjoid2hpdGUiLCJ0YXNrVGV4dENvbG9yIjoid2hpdGUiLCJ0YXNrVGV4dERhcmtDb2xvciI6ImJsYWNrIiwidGFza1RleHRPdXRzaWRlQ29sb3IiOiJibGFjayIsInRhc2tUZXh0Q2xpY2thYmxlQ29sb3IiOiIjMDAzMTYzIiwiYWN0aXZlVGFza0JvcmRlckNvbG9yIjoiIzUzNGZiYyIsImFjdGl2ZVRhc2tCa2dDb2xvciI6IiNiZmM3ZmYiLCJncmlkQ29sb3IiOiJsaWdodGdyZXkiLCJkb25lVGFza0JrZ0NvbG9yIjoibGlnaHRncmV5IiwiZG9uZVRhc2tCb3JkZXJDb2xvciI6ImdyZXkiLCJjcml0Qm9yZGVyQ29sb3IiOiIjZmY4ODg4IiwiY3JpdEJrZ0NvbG9yIjoicmVkIiwidG9kYXlMaW5lQ29sb3IiOiJyZWQiLCJsYWJlbENvbG9yIjoiYmxhY2siLCJlcnJvckJrZ0NvbG9yIjoiIzU1MjIyMiIsImVycm9yVGV4dENvbG9yIjoiIzU1MjIyMiIsImNsYXNzVGV4dCI6IiMxMzEzMDAiLCJmaWxsVHlwZTAiOiIjRUNFQ0ZGIiwiZmlsbFR5cGUxIjoiI2ZmZmZkZSIsImZpbGxUeXBlMiI6ImhzbCgzMDQsIDEwMCUsIDk2LjI3NDUwOTgwMzklKSIsImZpbGxUeXBlMyI6ImhzbCgxMjQsIDEwMCUsIDkzLjUyOTQxMTc2NDclKSIsImZpbGxUeXBlNCI6ImhzbCgxNzYsIDEwMCUsIDk2LjI3NDUwOTgwMzklKSIsImZpbGxUeXBlNSI6ImhzbCgtNCwgMTAwJSwgOTMuNTI5NDExNzY0NyUpIiwiZmlsbFR5cGU2IjoiaHNsKDgsIDEwMCUsIDk2LjI3NDUwOTgwMzklKSIsImZpbGxUeXBlNyI6ImhzbCgxODgsIDEwMCUsIDkzLjUyOTQxMTc2NDclKSJ9fSwidXBkYXRlRWRpdG9yIjpmYWxzZX0)](https://mermaid-js.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ3JhcGggVERcbiAgICBcbiAgICBVc2VyKChVc2VyKSkgLS0-IHxSZWFkIERvY3VtZW50fCBBcHBsaWNhdGlvblxuICAgIEFwcGxpY2F0aW9uIC0tPiB8Q2FuIFVzZXIgUmVhZHwgT1BBe0V2YWx1YXRlIFBvbGljeX1cbiAgICBPUEEgLS0-IHxHZXQgUG9saWN5fCBEeW5hbW9bKER5bmFtbyldXG4gICAgRHluYW1vIC0tPiBPUEFcbiAgICBPUEEgLS0-fFJlc3VsdHwgQXBwbGljYXRpb25cbiAgICBBcHBsaWNhdGlvbiAtLT4gfEFsbG93OiBSZXR1cm4gRG9jdW1lbnR8IFVzZXJcbiAgICBBcHBsaWNhdGlvbiAtLT4gfERlbnl8IEVycm9yXG4gICAgICAgICAgICAiLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCIsInRoZW1lVmFyaWFibGVzIjp7ImJhY2tncm91bmQiOiJ3aGl0ZSIsInByaW1hcnlDb2xvciI6IiNFQ0VDRkYiLCJzZWNvbmRhcnlDb2xvciI6IiNmZmZmZGUiLCJ0ZXJ0aWFyeUNvbG9yIjoiaHNsKDgwLCAxMDAlLCA5Ni4yNzQ1MDk4MDM5JSkiLCJwcmltYXJ5Qm9yZGVyQ29sb3IiOiJoc2woMjQwLCA2MCUsIDg2LjI3NDUwOTgwMzklKSIsInNlY29uZGFyeUJvcmRlckNvbG9yIjoiaHNsKDYwLCA2MCUsIDgzLjUyOTQxMTc2NDclKSIsInRlcnRpYXJ5Qm9yZGVyQ29sb3IiOiJoc2woODAsIDYwJSwgODYuMjc0NTA5ODAzOSUpIiwicHJpbWFyeVRleHRDb2xvciI6IiMxMzEzMDAiLCJzZWNvbmRhcnlUZXh0Q29sb3IiOiIjMDAwMDIxIiwidGVydGlhcnlUZXh0Q29sb3IiOiJyZ2IoOS41MDAwMDAwMDAxLCA5LjUwMDAwMDAwMDEsIDkuNTAwMDAwMDAwMSkiLCJsaW5lQ29sb3IiOiIjMzMzMzMzIiwidGV4dENvbG9yIjoiIzMzMyIsIm1haW5Ca2ciOiIjRUNFQ0ZGIiwic2Vjb25kQmtnIjoiI2ZmZmZkZSIsImJvcmRlcjEiOiIjOTM3MERCIiwiYm9yZGVyMiI6IiNhYWFhMzMiLCJhcnJvd2hlYWRDb2xvciI6IiMzMzMzMzMiLCJmb250RmFtaWx5IjoiXCJ0cmVidWNoZXQgbXNcIiwgdmVyZGFuYSwgYXJpYWwiLCJmb250U2l6ZSI6IjE2cHgiLCJsYWJlbEJhY2tncm91bmQiOiIjZThlOGU4Iiwibm9kZUJrZyI6IiNFQ0VDRkYiLCJub2RlQm9yZGVyIjoiIzkzNzBEQiIsImNsdXN0ZXJCa2ciOiIjZmZmZmRlIiwiY2x1c3RlckJvcmRlciI6IiNhYWFhMzMiLCJkZWZhdWx0TGlua0NvbG9yIjoiIzMzMzMzMyIsInRpdGxlQ29sb3IiOiIjMzMzIiwiZWRnZUxhYmVsQmFja2dyb3VuZCI6IiNlOGU4ZTgiLCJhY3RvckJvcmRlciI6ImhzbCgyNTkuNjI2MTY4MjI0MywgNTkuNzc2NTM2MzEyOCUsIDg3LjkwMTk2MDc4NDMlKSIsImFjdG9yQmtnIjoiI0VDRUNGRiIsImFjdG9yVGV4dENvbG9yIjoiYmxhY2siLCJhY3RvckxpbmVDb2xvciI6ImdyZXkiLCJzaWduYWxDb2xvciI6IiMzMzMiLCJzaWduYWxUZXh0Q29sb3IiOiIjMzMzIiwibGFiZWxCb3hCa2dDb2xvciI6IiNFQ0VDRkYiLCJsYWJlbEJveEJvcmRlckNvbG9yIjoiaHNsKDI1OS42MjYxNjgyMjQzLCA1OS43NzY1MzYzMTI4JSwgODcuOTAxOTYwNzg0MyUpIiwibGFiZWxUZXh0Q29sb3IiOiJibGFjayIsImxvb3BUZXh0Q29sb3IiOiJibGFjayIsIm5vdGVCb3JkZXJDb2xvciI6IiNhYWFhMzMiLCJub3RlQmtnQ29sb3IiOiIjZmZmNWFkIiwibm90ZVRleHRDb2xvciI6ImJsYWNrIiwiYWN0aXZhdGlvbkJvcmRlckNvbG9yIjoiIzY2NiIsImFjdGl2YXRpb25Ca2dDb2xvciI6IiNmNGY0ZjQiLCJzZXF1ZW5jZU51bWJlckNvbG9yIjoid2hpdGUiLCJzZWN0aW9uQmtnQ29sb3IiOiJyZ2JhKDEwMiwgMTAyLCAyNTUsIDAuNDkpIiwiYWx0U2VjdGlvbkJrZ0NvbG9yIjoid2hpdGUiLCJzZWN0aW9uQmtnQ29sb3IyIjoiI2ZmZjQwMCIsInRhc2tCb3JkZXJDb2xvciI6IiM1MzRmYmMiLCJ0YXNrQmtnQ29sb3IiOiIjOGE5MGRkIiwidGFza1RleHRMaWdodENvbG9yIjoid2hpdGUiLCJ0YXNrVGV4dENvbG9yIjoid2hpdGUiLCJ0YXNrVGV4dERhcmtDb2xvciI6ImJsYWNrIiwidGFza1RleHRPdXRzaWRlQ29sb3IiOiJibGFjayIsInRhc2tUZXh0Q2xpY2thYmxlQ29sb3IiOiIjMDAzMTYzIiwiYWN0aXZlVGFza0JvcmRlckNvbG9yIjoiIzUzNGZiYyIsImFjdGl2ZVRhc2tCa2dDb2xvciI6IiNiZmM3ZmYiLCJncmlkQ29sb3IiOiJsaWdodGdyZXkiLCJkb25lVGFza0JrZ0NvbG9yIjoibGlnaHRncmV5IiwiZG9uZVRhc2tCb3JkZXJDb2xvciI6ImdyZXkiLCJjcml0Qm9yZGVyQ29sb3IiOiIjZmY4ODg4IiwiY3JpdEJrZ0NvbG9yIjoicmVkIiwidG9kYXlMaW5lQ29sb3IiOiJyZWQiLCJsYWJlbENvbG9yIjoiYmxhY2siLCJlcnJvckJrZ0NvbG9yIjoiIzU1MjIyMiIsImVycm9yVGV4dENvbG9yIjoiIzU1MjIyMiIsImNsYXNzVGV4dCI6IiMxMzEzMDAiLCJmaWxsVHlwZTAiOiIjRUNFQ0ZGIiwiZmlsbFR5cGUxIjoiI2ZmZmZkZSIsImZpbGxUeXBlMiI6ImhzbCgzMDQsIDEwMCUsIDk2LjI3NDUwOTgwMzklKSIsImZpbGxUeXBlMyI6ImhzbCgxMjQsIDEwMCUsIDkzLjUyOTQxMTc2NDclKSIsImZpbGxUeXBlNCI6ImhzbCgxNzYsIDEwMCUsIDk2LjI3NDUwOTgwMzklKSIsImZpbGxUeXBlNSI6ImhzbCgtNCwgMTAwJSwgOTMuNTI5NDExNzY0NyUpIiwiZmlsbFR5cGU2IjoiaHNsKDgsIDEwMCUsIDk2LjI3NDUwOTgwMzklKSIsImZpbGxUeXBlNyI6ImhzbCgxODgsIDEwMCUsIDkzLjUyOTQxMTc2NDclKSJ9fSwidXBkYXRlRWRpdG9yIjpmYWxzZX0) + diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..3523b79 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,21 @@ + + + + + Document + + + + + + +
+ + + + From 164d1f262d260ba39f96d3248989ebda6e28378f Mon Sep 17 00:00:00 2001 From: Michael Neil Date: Wed, 28 Oct 2020 00:49:07 -0700 Subject: [PATCH 02/11] Update documentation scaffold with placeholders --- README.md | 4 ++-- docs/README.md | 4 ++-- docs/_coverpage.md | 11 +++++++++++ docs/_sidebar.md | 13 +++++++++++++ docs/changelog.md | 1 + docs/configuration.md | 1 + docs/deploy.md | 1 + docs/index.html | 6 ++++-- docs/quickstart.md | 1 + 9 files changed, 36 insertions(+), 6 deletions(-) create mode 100644 docs/_coverpage.md create mode 100644 docs/_sidebar.md create mode 100644 docs/changelog.md create mode 100644 docs/configuration.md create mode 100644 docs/deploy.md create mode 100644 docs/quickstart.md diff --git a/README.md b/README.md index edc290a..fd9b3cd 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # OPA DynamoDB -Infinitely scalable policy store with instantaneous policy updates for use by small and enterprise scale teams wanting to use Open Policy Agent. +Scalable policy store with real-time policy updates for use by small and enterprise scale teams wanting to use Open Policy Agent. OPA DynamoDB adds custom functionality to rego policies to query data from DynamoDB. @@ -14,7 +14,7 @@ OPA has several strategies for managing policies at scale and accepting internal DynamoDB is an excellent backend for policy data. You can store documentesque data across dynamo rows and query them using a collections pattern. This method is efficient (single read to get entire policy) and scalable (dynamodb storage is extremely scalable). -If you want to understand more about Single Table Design, item collections, and DynamoDB in general I recommend this book by Alex Debrie https://www.dynamodbbook.com/. I have no affiliation with Alex or his book. It's that good. +If you want to understand more about Single Table Design, item collections, and DynamoDB in general I recommend this book by Alex Debrie https://www.dynamodbbook.com/. I have no affiliation with Alex or his book. ## Architecture diff --git a/docs/README.md b/docs/README.md index edc290a..fd9b3cd 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,6 +1,6 @@ # OPA DynamoDB -Infinitely scalable policy store with instantaneous policy updates for use by small and enterprise scale teams wanting to use Open Policy Agent. +Scalable policy store with real-time policy updates for use by small and enterprise scale teams wanting to use Open Policy Agent. OPA DynamoDB adds custom functionality to rego policies to query data from DynamoDB. @@ -14,7 +14,7 @@ OPA has several strategies for managing policies at scale and accepting internal DynamoDB is an excellent backend for policy data. You can store documentesque data across dynamo rows and query them using a collections pattern. This method is efficient (single read to get entire policy) and scalable (dynamodb storage is extremely scalable). -If you want to understand more about Single Table Design, item collections, and DynamoDB in general I recommend this book by Alex Debrie https://www.dynamodbbook.com/. I have no affiliation with Alex or his book. It's that good. +If you want to understand more about Single Table Design, item collections, and DynamoDB in general I recommend this book by Alex Debrie https://www.dynamodbbook.com/. I have no affiliation with Alex or his book. ## Architecture diff --git a/docs/_coverpage.md b/docs/_coverpage.md new file mode 100644 index 0000000..c8d6937 --- /dev/null +++ b/docs/_coverpage.md @@ -0,0 +1,11 @@ + +# OPA DynamoDB 0.2 + +> DynamoDB Backend for Open Policy Agent + +- Simple and lightweight +- No statically built html files +- Multiple themes + +[GitHub](https://github.com/mneil/opa-dynamodb/) +[Get Started](#docsify) diff --git a/docs/_sidebar.md b/docs/_sidebar.md new file mode 100644 index 0000000..f4ec517 --- /dev/null +++ b/docs/_sidebar.md @@ -0,0 +1,13 @@ +- Getting started + + - [Quick start](quickstart.md) + +- Customization + + - [Configuration](configuration.md) + +- Guide + + - [Deploy](deploy.md) + +- [Changelog](changelog.md) \ No newline at end of file diff --git a/docs/changelog.md b/docs/changelog.md new file mode 100644 index 0000000..5ddad42 --- /dev/null +++ b/docs/changelog.md @@ -0,0 +1 @@ +# Changelog \ No newline at end of file diff --git a/docs/configuration.md b/docs/configuration.md new file mode 100644 index 0000000..af4abbf --- /dev/null +++ b/docs/configuration.md @@ -0,0 +1 @@ +# Configuration \ No newline at end of file diff --git a/docs/deploy.md b/docs/deploy.md new file mode 100644 index 0000000..4a8d593 --- /dev/null +++ b/docs/deploy.md @@ -0,0 +1 @@ +# Deploy \ No newline at end of file diff --git a/docs/index.html b/docs/index.html index 3523b79..09b23be 100644 --- a/docs/index.html +++ b/docs/index.html @@ -12,8 +12,10 @@
diff --git a/docs/quickstart.md b/docs/quickstart.md new file mode 100644 index 0000000..1d2e852 --- /dev/null +++ b/docs/quickstart.md @@ -0,0 +1 @@ +# Quick Start \ No newline at end of file From 17c1759a8275a903111b2e1b2924125cfec0f5f1 Mon Sep 17 00:00:00 2001 From: Michael Neil Date: Wed, 28 Oct 2020 00:49:27 -0700 Subject: [PATCH 03/11] Add a fargate template to reference in the docs --- templates/fargate.yml | 315 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 315 insertions(+) create mode 100644 templates/fargate.yml diff --git a/templates/fargate.yml b/templates/fargate.yml new file mode 100644 index 0000000..6fb49ad --- /dev/null +++ b/templates/fargate.yml @@ -0,0 +1,315 @@ +AWSTemplateFormatVersion: 2010-09-09 +Description: | + Deploy OPA DynamoDB to aws Fargate Modified from + https://github.com/1Strategy/fargate-cloudformation-example +Parameters: + VPC: + Type: AWS::EC2::VPC::Id + SubnetA: + Type: AWS::EC2::Subnet::Id + SubnetB: + Type: AWS::EC2::Subnet::Id + Certificate: + Type: String + Default: arn:aws:acm:region:123456789012:certificate/00000000-0000-0000-0000-000000000000 + Image: + Type: String + Default: opa-dynamodb:latest + ServiceName: + Type: String + Default: OPADynamoDB + ContainerPort: + Type: Number + Default: 80 + LoadBalancerPort: + Type: Number + Default: 443 + HealthCheckPath: + Type: String + Default: /healthcheck + HostedZoneName: + Type: String + Subdomain: + Type: String + Default: opa + MinContainers: + Type: Number + Default: 2 + MaxContainers: + Type: Number + Default: 10 + AutoScalingTargetValue: + Type: Number + Default: 50 + +Resources: + Cluster: + Type: AWS::ECS::Cluster + Properties: + ClusterName: !Join ['', [!Ref ServiceName, Cluster]] + TaskDefinition: + Type: AWS::ECS::TaskDefinition + DependsOn: LogGroup + Properties: + Family: !Join ['', [!Ref ServiceName, TaskDefinition]] + NetworkMode: awsvpc + RequiresCompatibilities: + - FARGATE + Cpu: 1024 + Memory: 1GB + ExecutionRoleArn: !Ref ExecutionRole + TaskRoleArn: !Ref TaskRole + ContainerDefinitions: + - Name: !Ref ServiceName + Image: !Ref Image + PortMappings: + - ContainerPort: !Ref ContainerPort + LogConfiguration: + LogDriver: awslogs + Options: + awslogs-region: !Ref AWS::Region + awslogs-group: !Ref LogGroup + awslogs-stream-prefix: ecs + ExecutionRole: + Type: AWS::IAM::Role + Properties: + RoleName: !Join ['', [!Ref ServiceName, ExecutionRole]] + AssumeRolePolicyDocument: + Statement: + - Effect: Allow + Principal: + Service: ecs-tasks.amazonaws.com + Action: sts:AssumeRole + ManagedPolicyArns: + - arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy + TaskRole: + Type: AWS::IAM::Role + Properties: + RoleName: !Join ['', [!Ref ServiceName, TaskRole]] + AssumeRolePolicyDocument: + Statement: + - Effect: Allow + Principal: + Service: ecs-tasks.amazonaws.com + Action: sts:AssumeRole + TaskPolicy: + Type: AWS::IAM::Policy + Properties: + PolicyName: OpaDynamoTaskPolicy + Roles: + - !Ref TaskRole + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - dynamodb:ConditionCheckItem + - dynamodb:DeleteItem + - dynamodb:GetItem + - dynamodb:PutItem + - dynamodb:Query + - dynamodb:UpdateItem + Resource: + - '*' + AutoScalingRole: + Type: AWS::IAM::Role + Properties: + RoleName: !Join ['', [!Ref ServiceName, AutoScalingRole]] + AssumeRolePolicyDocument: + Statement: + - Effect: Allow + Principal: + Service: ecs-tasks.amazonaws.com + Action: sts:AssumeRole + ManagedPolicyArns: + - arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceAutoscaleRole + ContainerSecurityGroup: + Type: AWS::EC2::SecurityGroup + Properties: + GroupDescription: !Join ['', [!Ref ServiceName, ContainerSecurityGroup]] + VpcId: !Ref VPC + SecurityGroupIngress: + - IpProtocol: tcp + FromPort: !Ref ContainerPort + ToPort: !Ref ContainerPort + SourceSecurityGroupId: !Ref LoadBalancerSecurityGroup + LoadBalancerSecurityGroup: + Type: AWS::EC2::SecurityGroup + Properties: + GroupDescription: !Join ['', [!Ref ServiceName, LoadBalancerSecurityGroup]] + VpcId: !Ref VPC + SecurityGroupIngress: + - IpProtocol: tcp + FromPort: !Ref LoadBalancerPort + ToPort: !Ref LoadBalancerPort + CidrIp: 0.0.0.0/0 + Service: + Type: AWS::ECS::Service + DependsOn: + - ListenerHTTPS + Properties: + ServiceName: !Ref ServiceName + Cluster: !Ref Cluster + TaskDefinition: !Ref TaskDefinition + DeploymentConfiguration: + MinimumHealthyPercent: 100 + MaximumPercent: 200 + DesiredCount: 2 + HealthCheckGracePeriodSeconds: 30 + LaunchType: FARGATE + NetworkConfiguration: + AwsvpcConfiguration: + AssignPublicIp: ENABLED + Subnets: + - !Ref SubnetA + - !Ref SubnetB + SecurityGroups: + - !Ref ContainerSecurityGroup + LoadBalancers: + - ContainerName: !Ref ServiceName + ContainerPort: !Ref ContainerPort + TargetGroupArn: !Ref TargetGroup + TargetGroup: + Type: AWS::ElasticLoadBalancingV2::TargetGroup + Properties: + HealthCheckIntervalSeconds: 10 + HealthCheckPath: !Ref HealthCheckPath + HealthCheckTimeoutSeconds: 5 + UnhealthyThresholdCount: 2 + HealthyThresholdCount: 2 + Name: !Join ['', [!Ref ServiceName, TargetGroup]] + Port: !Ref ContainerPort + Protocol: HTTP + TargetGroupAttributes: + - Key: deregistration_delay.timeout_seconds + Value: 60 + TargetType: ip + VpcId: !Ref VPC + ListenerHTTPS: + Type: AWS::ElasticLoadBalancingV2::Listener + Properties: + DefaultActions: + - TargetGroupArn: !Ref TargetGroup + Type: forward + LoadBalancerArn: !Ref LoadBalancer + Port: !Ref LoadBalancerPort + Protocol: HTTPS + Certificates: + - CertificateArn: !Ref Certificate + LoadBalancer: + Type: AWS::ElasticLoadBalancingV2::LoadBalancer + Properties: + LoadBalancerAttributes: + - Key: idle_timeout.timeout_seconds + Value: 60 + Name: !Join ['', [!Ref ServiceName, LoadBalancer]] + Scheme: internet-facing + SecurityGroups: + - !Ref LoadBalancerSecurityGroup + Subnets: + - !Ref SubnetA + - !Ref SubnetB + DNSRecord: + Type: AWS::Route53::RecordSet + Properties: + HostedZoneName: !Join ['', [!Ref HostedZoneName, .]] + Name: !Join ['', [!Ref Subdomain, ., !Ref HostedZoneName, .]] + Type: A + AliasTarget: + DNSName: !GetAtt LoadBalancer.DNSName + HostedZoneId: !GetAtt LoadBalancer.CanonicalHostedZoneID + LogGroup: + Type: AWS::Logs::LogGroup + Properties: + LogGroupName: !Join ['', [/ecs/, !Ref ServiceName, TaskDefinition]] + AutoScalingTarget: + Type: AWS::ApplicationAutoScaling::ScalableTarget + Properties: + MinCapacity: !Ref MinContainers + MaxCapacity: !Ref MaxContainers + ResourceId: !Join ['/', [service, !Ref Cluster, !GetAtt Service.Name]] + ScalableDimension: ecs:service:DesiredCount + ServiceNamespace: ecs + RoleARN: !GetAtt AutoScalingRole.Arn + AutoScalingPolicy: + Type: AWS::ApplicationAutoScaling::ScalingPolicy + Properties: + PolicyName: !Join ['', [!Ref ServiceName, AutoScalingPolicy]] + PolicyType: TargetTrackingScaling + ScalingTargetId: !Ref AutoScalingTarget + TargetTrackingScalingPolicyConfiguration: + PredefinedMetricSpecification: + PredefinedMetricType: ECSServiceAverageCPUUtilization + ScaleInCooldown: 10 + ScaleOutCooldown: 10 + TargetValue: !Ref AutoScalingTargetValue + DynamoTable: + Type: AWS::DynamoDB::Table + Properties: + AttributeDefinitions: + - AttributeName: PK + AttributeType: S + - AttributeName: SK + AttributeType: S + BillingMode: PAY_PER_REQUEST + KeySchema: + - AttributeName: PK + KeyType: HASH + - AttributeName: SK + KeyType: RANGE + PointInTimeRecoverySpecification: + PointInTimeRecoveryEnabled: True + SSESpecification: + KMSMasterKeyId: String + SSEEnabled: True + SSEType: KMS + TableName: OpaDynamoDB + DynamoKey: + Type: AWS::KMS::Key + Properties: + Description: A KMS Key for OPA DynamoDB Table + Enabled: True + EnableKeyRotation: True + KeyPolicy: + Version: 2012-10-17 + Statement: + - Sid : Allow access through Amazon DynamoDB for all principals in the account that are authorized to use Amazon DynamoDB + Effect : Allow + Principal : + AWS : '*' + Action: + - kms:Encrypt + - kms:Decrypt + - kms:ReEncrypt* + - kms:GenerateDataKey* + - kms:CreateGrant + - kms:DescribeKey + Resource: '*' + Condition: + StringEquals: + kms:CallerAccount: !Ref AWS::AccountId + kms:ViaService: !Sub dynamodb.${AWS::Region}.amazonaws.com + - Sid: Allow direct access to key metadata to the account + Effect: Allow + Principal: + AWS : !Sub arn:aws:iam::${AWS::AccountId}:root + Action: + - kms:Describe* + - kms:Get* + - kms:List* + - kms:RevokeGrant + Resource : '*' + - Sid: Allow DynamoDB Service with service principal name dynamodb.amazonaws.com to describe the key directly + Effect: Allow + Principal: + Service: dynamodb.amazonaws.com + Action: + - kms:Describe* + - kms:Get* + - kms:List* + Resource : '*' + +Outputs: + Endpoint: + Description: Endpoint + Value: !Join ['', ['https://', !Ref DNSRecord]] \ No newline at end of file From 8e4c7437016661c39a07f40766292cb7b0c47deb Mon Sep 17 00:00:00 2001 From: Michael Neil Date: Sun, 17 Jan 2021 09:41:32 -0800 Subject: [PATCH 04/11] Rearrange pages and add configuration table --- docs/_coverpage.md | 13 +++++++------ docs/_sidebar.md | 12 +++--------- docs/changelog.md | 12 +++++++++++- docs/configuration.md | 11 ++++++++++- 4 files changed, 31 insertions(+), 17 deletions(-) diff --git a/docs/_coverpage.md b/docs/_coverpage.md index c8d6937..872cd31 100644 --- a/docs/_coverpage.md +++ b/docs/_coverpage.md @@ -1,11 +1,12 @@ -# OPA DynamoDB 0.2 +# OPA DynamoDB 0.1.0 > DynamoDB Backend for Open Policy Agent -- Simple and lightweight -- No statically built html files -- Multiple themes - [GitHub](https://github.com/mneil/opa-dynamodb/) -[Get Started](#docsify) +[Get Started](#opa-dynamodb) + + + + +![color](linear-gradient(to-right,#C4B3FF,#DAFFB3)) diff --git a/docs/_sidebar.md b/docs/_sidebar.md index f4ec517..9125ac5 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -1,13 +1,7 @@ -- Getting started - - - [Quick start](quickstart.md) - -- Customization - - - [Configuration](configuration.md) +- [Getting started](quickstart.md) - Guide - + - [Configuration](configuration.md) - [Deploy](deploy.md) -- [Changelog](changelog.md) \ No newline at end of file +- [Changelog](changelog.md) diff --git a/docs/changelog.md b/docs/changelog.md index 5ddad42..7740976 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1 +1,11 @@ -# Changelog \ No newline at end of file +# Changelog + +## v0.1.0 + +Initial Release + +Working dynamodb backend with assumptions: + + - Must have both a hash key and range key on your primary partition + - Assumed PK and SK for the key names but can be overridden with environment variables + - Tests exist to prove functionality diff --git a/docs/configuration.md b/docs/configuration.md index af4abbf..d06a853 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -1 +1,10 @@ -# Configuration \ No newline at end of file +# Configuration + +OPA DynamoDB can be configured using environment variable. This table describes the default settings and the variable that you can set to change them. + +| Variable | Default | Required | Description | +|--------------|-------------|----------|------------------------------------------------------| +| DYNAMO_TABLE | OpaDynamoDB | No | The name of the table to get data from | +| DYNAMO_PK | PK | No | The hash (partition) key of the primary partition | +| DYNAMO_SK | SK | No | The sort (range) key of the primary partition | +| ENDPOINT_URL | "" | No | DynamoDB API url. Useful for testing w/ dynamo local | From d62e86f3f558f56076ca29f45fc20fd95da5b723 Mon Sep 17 00:00:00 2001 From: Michael Neil Date: Sun, 17 Jan 2021 09:44:09 -0800 Subject: [PATCH 05/11] Link to the github pages documentation --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index fd9b3cd..1b764b0 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,8 @@ OPA has several strategies for managing policies at scale and accepting internal - AWS credentials can be infered by the credentials chain in Goland AWS SDK - Retry logic and caching are implemented by the AWS SDK and this implementation +See the [User Documentation](https://mneil.github.io/opa-dynamodb) for setup and usage. + ## DynamoDB As A Backend DynamoDB is an excellent backend for policy data. You can store documentesque data across dynamo rows and query them using a collections pattern. This method is efficient (single read to get entire policy) and scalable (dynamodb storage is extremely scalable). From 456011fa83c1539b3927efb764437e5fa50d57ae Mon Sep 17 00:00:00 2001 From: Michael Neil Date: Sun, 17 Jan 2021 12:34:27 -0800 Subject: [PATCH 06/11] Add quickstart with examples for docker compose --- docs/README.md | 13 +------ docs/examples/docker-compose.yml | 40 ++++++++++++++++++++ docs/examples/rbac.rego | 24 ++++++++++++ docs/images/table-creation.png | Bin 0 -> 18053 bytes docs/quickstart.md | 62 ++++++++++++++++++++++++++++++- 5 files changed, 127 insertions(+), 12 deletions(-) create mode 100644 docs/examples/docker-compose.yml create mode 100644 docs/examples/rbac.rego create mode 100644 docs/images/table-creation.png diff --git a/docs/README.md b/docs/README.md index fd9b3cd..2cf4234 100644 --- a/docs/README.md +++ b/docs/README.md @@ -10,15 +10,6 @@ OPA has several strategies for managing policies at scale and accepting internal - AWS credentials can be infered by the credentials chain in Goland AWS SDK - Retry logic and caching are implemented by the AWS SDK and this implementation -## DynamoDB As A Backend - -DynamoDB is an excellent backend for policy data. You can store documentesque data across dynamo rows and query them using a collections pattern. This method is efficient (single read to get entire policy) and scalable (dynamodb storage is extremely scalable). - -If you want to understand more about Single Table Design, item collections, and DynamoDB in general I recommend this book by Alex Debrie https://www.dynamodbbook.com/. I have no affiliation with Alex or his book. - -## Architecture - -This high level flow diagram shows how we can check if a user attempting to get a document has access to this document or not. - -[![](https://mermaid.ink/img/eyJjb2RlIjoiZ3JhcGggVERcbiAgICBcbiAgICBVc2VyKChVc2VyKSkgLS0-IHxSZWFkIERvY3VtZW50fCBBcHBsaWNhdGlvblxuICAgIEFwcGxpY2F0aW9uIC0tPiB8Q2FuIFVzZXIgUmVhZHwgT1BBe0V2YWx1YXRlIFBvbGljeX1cbiAgICBPUEEgLS0-IHxHZXQgUG9saWN5fCBEeW5hbW9bKER5bmFtbyldXG4gICAgRHluYW1vIC0tPiBPUEFcbiAgICBPUEEgLS0-fFJlc3VsdHwgQXBwbGljYXRpb25cbiAgICBBcHBsaWNhdGlvbiAtLT4gfEFsbG93OiBSZXR1cm4gRG9jdW1lbnR8IFVzZXJcbiAgICBBcHBsaWNhdGlvbiAtLT4gfERlbnl8IEVycm9yXG4gICAgICAgICAgICAiLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCIsInRoZW1lVmFyaWFibGVzIjp7ImJhY2tncm91bmQiOiJ3aGl0ZSIsInByaW1hcnlDb2xvciI6IiNFQ0VDRkYiLCJzZWNvbmRhcnlDb2xvciI6IiNmZmZmZGUiLCJ0ZXJ0aWFyeUNvbG9yIjoiaHNsKDgwLCAxMDAlLCA5Ni4yNzQ1MDk4MDM5JSkiLCJwcmltYXJ5Qm9yZGVyQ29sb3IiOiJoc2woMjQwLCA2MCUsIDg2LjI3NDUwOTgwMzklKSIsInNlY29uZGFyeUJvcmRlckNvbG9yIjoiaHNsKDYwLCA2MCUsIDgzLjUyOTQxMTc2NDclKSIsInRlcnRpYXJ5Qm9yZGVyQ29sb3IiOiJoc2woODAsIDYwJSwgODYuMjc0NTA5ODAzOSUpIiwicHJpbWFyeVRleHRDb2xvciI6IiMxMzEzMDAiLCJzZWNvbmRhcnlUZXh0Q29sb3IiOiIjMDAwMDIxIiwidGVydGlhcnlUZXh0Q29sb3IiOiJyZ2IoOS41MDAwMDAwMDAxLCA5LjUwMDAwMDAwMDEsIDkuNTAwMDAwMDAwMSkiLCJsaW5lQ29sb3IiOiIjMzMzMzMzIiwidGV4dENvbG9yIjoiIzMzMyIsIm1haW5Ca2ciOiIjRUNFQ0ZGIiwic2Vjb25kQmtnIjoiI2ZmZmZkZSIsImJvcmRlcjEiOiIjOTM3MERCIiwiYm9yZGVyMiI6IiNhYWFhMzMiLCJhcnJvd2hlYWRDb2xvciI6IiMzMzMzMzMiLCJmb250RmFtaWx5IjoiXCJ0cmVidWNoZXQgbXNcIiwgdmVyZGFuYSwgYXJpYWwiLCJmb250U2l6ZSI6IjE2cHgiLCJsYWJlbEJhY2tncm91bmQiOiIjZThlOGU4Iiwibm9kZUJrZyI6IiNFQ0VDRkYiLCJub2RlQm9yZGVyIjoiIzkzNzBEQiIsImNsdXN0ZXJCa2ciOiIjZmZmZmRlIiwiY2x1c3RlckJvcmRlciI6IiNhYWFhMzMiLCJkZWZhdWx0TGlua0NvbG9yIjoiIzMzMzMzMyIsInRpdGxlQ29sb3IiOiIjMzMzIiwiZWRnZUxhYmVsQmFja2dyb3VuZCI6IiNlOGU4ZTgiLCJhY3RvckJvcmRlciI6ImhzbCgyNTkuNjI2MTY4MjI0MywgNTkuNzc2NTM2MzEyOCUsIDg3LjkwMTk2MDc4NDMlKSIsImFjdG9yQmtnIjoiI0VDRUNGRiIsImFjdG9yVGV4dENvbG9yIjoiYmxhY2siLCJhY3RvckxpbmVDb2xvciI6ImdyZXkiLCJzaWduYWxDb2xvciI6IiMzMzMiLCJzaWduYWxUZXh0Q29sb3IiOiIjMzMzIiwibGFiZWxCb3hCa2dDb2xvciI6IiNFQ0VDRkYiLCJsYWJlbEJveEJvcmRlckNvbG9yIjoiaHNsKDI1OS42MjYxNjgyMjQzLCA1OS43NzY1MzYzMTI4JSwgODcuOTAxOTYwNzg0MyUpIiwibGFiZWxUZXh0Q29sb3IiOiJibGFjayIsImxvb3BUZXh0Q29sb3IiOiJibGFjayIsIm5vdGVCb3JkZXJDb2xvciI6IiNhYWFhMzMiLCJub3RlQmtnQ29sb3IiOiIjZmZmNWFkIiwibm90ZVRleHRDb2xvciI6ImJsYWNrIiwiYWN0aXZhdGlvbkJvcmRlckNvbG9yIjoiIzY2NiIsImFjdGl2YXRpb25Ca2dDb2xvciI6IiNmNGY0ZjQiLCJzZXF1ZW5jZU51bWJlckNvbG9yIjoid2hpdGUiLCJzZWN0aW9uQmtnQ29sb3IiOiJyZ2JhKDEwMiwgMTAyLCAyNTUsIDAuNDkpIiwiYWx0U2VjdGlvbkJrZ0NvbG9yIjoid2hpdGUiLCJzZWN0aW9uQmtnQ29sb3IyIjoiI2ZmZjQwMCIsInRhc2tCb3JkZXJDb2xvciI6IiM1MzRmYmMiLCJ0YXNrQmtnQ29sb3IiOiIjOGE5MGRkIiwidGFza1RleHRMaWdodENvbG9yIjoid2hpdGUiLCJ0YXNrVGV4dENvbG9yIjoid2hpdGUiLCJ0YXNrVGV4dERhcmtDb2xvciI6ImJsYWNrIiwidGFza1RleHRPdXRzaWRlQ29sb3IiOiJibGFjayIsInRhc2tUZXh0Q2xpY2thYmxlQ29sb3IiOiIjMDAzMTYzIiwiYWN0aXZlVGFza0JvcmRlckNvbG9yIjoiIzUzNGZiYyIsImFjdGl2ZVRhc2tCa2dDb2xvciI6IiNiZmM3ZmYiLCJncmlkQ29sb3IiOiJsaWdodGdyZXkiLCJkb25lVGFza0JrZ0NvbG9yIjoibGlnaHRncmV5IiwiZG9uZVRhc2tCb3JkZXJDb2xvciI6ImdyZXkiLCJjcml0Qm9yZGVyQ29sb3IiOiIjZmY4ODg4IiwiY3JpdEJrZ0NvbG9yIjoicmVkIiwidG9kYXlMaW5lQ29sb3IiOiJyZWQiLCJsYWJlbENvbG9yIjoiYmxhY2siLCJlcnJvckJrZ0NvbG9yIjoiIzU1MjIyMiIsImVycm9yVGV4dENvbG9yIjoiIzU1MjIyMiIsImNsYXNzVGV4dCI6IiMxMzEzMDAiLCJmaWxsVHlwZTAiOiIjRUNFQ0ZGIiwiZmlsbFR5cGUxIjoiI2ZmZmZkZSIsImZpbGxUeXBlMiI6ImhzbCgzMDQsIDEwMCUsIDk2LjI3NDUwOTgwMzklKSIsImZpbGxUeXBlMyI6ImhzbCgxMjQsIDEwMCUsIDkzLjUyOTQxMTc2NDclKSIsImZpbGxUeXBlNCI6ImhzbCgxNzYsIDEwMCUsIDk2LjI3NDUwOTgwMzklKSIsImZpbGxUeXBlNSI6ImhzbCgtNCwgMTAwJSwgOTMuNTI5NDExNzY0NyUpIiwiZmlsbFR5cGU2IjoiaHNsKDgsIDEwMCUsIDk2LjI3NDUwOTgwMzklKSIsImZpbGxUeXBlNyI6ImhzbCgxODgsIDEwMCUsIDkzLjUyOTQxMTc2NDclKSJ9fSwidXBkYXRlRWRpdG9yIjpmYWxzZX0)](https://mermaid-js.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ3JhcGggVERcbiAgICBcbiAgICBVc2VyKChVc2VyKSkgLS0-IHxSZWFkIERvY3VtZW50fCBBcHBsaWNhdGlvblxuICAgIEFwcGxpY2F0aW9uIC0tPiB8Q2FuIFVzZXIgUmVhZHwgT1BBe0V2YWx1YXRlIFBvbGljeX1cbiAgICBPUEEgLS0-IHxHZXQgUG9saWN5fCBEeW5hbW9bKER5bmFtbyldXG4gICAgRHluYW1vIC0tPiBPUEFcbiAgICBPUEEgLS0-fFJlc3VsdHwgQXBwbGljYXRpb25cbiAgICBBcHBsaWNhdGlvbiAtLT4gfEFsbG93OiBSZXR1cm4gRG9jdW1lbnR8IFVzZXJcbiAgICBBcHBsaWNhdGlvbiAtLT4gfERlbnl8IEVycm9yXG4gICAgICAgICAgICAiLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCIsInRoZW1lVmFyaWFibGVzIjp7ImJhY2tncm91bmQiOiJ3aGl0ZSIsInByaW1hcnlDb2xvciI6IiNFQ0VDRkYiLCJzZWNvbmRhcnlDb2xvciI6IiNmZmZmZGUiLCJ0ZXJ0aWFyeUNvbG9yIjoiaHNsKDgwLCAxMDAlLCA5Ni4yNzQ1MDk4MDM5JSkiLCJwcmltYXJ5Qm9yZGVyQ29sb3IiOiJoc2woMjQwLCA2MCUsIDg2LjI3NDUwOTgwMzklKSIsInNlY29uZGFyeUJvcmRlckNvbG9yIjoiaHNsKDYwLCA2MCUsIDgzLjUyOTQxMTc2NDclKSIsInRlcnRpYXJ5Qm9yZGVyQ29sb3IiOiJoc2woODAsIDYwJSwgODYuMjc0NTA5ODAzOSUpIiwicHJpbWFyeVRleHRDb2xvciI6IiMxMzEzMDAiLCJzZWNvbmRhcnlUZXh0Q29sb3IiOiIjMDAwMDIxIiwidGVydGlhcnlUZXh0Q29sb3IiOiJyZ2IoOS41MDAwMDAwMDAxLCA5LjUwMDAwMDAwMDEsIDkuNTAwMDAwMDAwMSkiLCJsaW5lQ29sb3IiOiIjMzMzMzMzIiwidGV4dENvbG9yIjoiIzMzMyIsIm1haW5Ca2ciOiIjRUNFQ0ZGIiwic2Vjb25kQmtnIjoiI2ZmZmZkZSIsImJvcmRlcjEiOiIjOTM3MERCIiwiYm9yZGVyMiI6IiNhYWFhMzMiLCJhcnJvd2hlYWRDb2xvciI6IiMzMzMzMzMiLCJmb250RmFtaWx5IjoiXCJ0cmVidWNoZXQgbXNcIiwgdmVyZGFuYSwgYXJpYWwiLCJmb250U2l6ZSI6IjE2cHgiLCJsYWJlbEJhY2tncm91bmQiOiIjZThlOGU4Iiwibm9kZUJrZyI6IiNFQ0VDRkYiLCJub2RlQm9yZGVyIjoiIzkzNzBEQiIsImNsdXN0ZXJCa2ciOiIjZmZmZmRlIiwiY2x1c3RlckJvcmRlciI6IiNhYWFhMzMiLCJkZWZhdWx0TGlua0NvbG9yIjoiIzMzMzMzMyIsInRpdGxlQ29sb3IiOiIjMzMzIiwiZWRnZUxhYmVsQmFja2dyb3VuZCI6IiNlOGU4ZTgiLCJhY3RvckJvcmRlciI6ImhzbCgyNTkuNjI2MTY4MjI0MywgNTkuNzc2NTM2MzEyOCUsIDg3LjkwMTk2MDc4NDMlKSIsImFjdG9yQmtnIjoiI0VDRUNGRiIsImFjdG9yVGV4dENvbG9yIjoiYmxhY2siLCJhY3RvckxpbmVDb2xvciI6ImdyZXkiLCJzaWduYWxDb2xvciI6IiMzMzMiLCJzaWduYWxUZXh0Q29sb3IiOiIjMzMzIiwibGFiZWxCb3hCa2dDb2xvciI6IiNFQ0VDRkYiLCJsYWJlbEJveEJvcmRlckNvbG9yIjoiaHNsKDI1OS42MjYxNjgyMjQzLCA1OS43NzY1MzYzMTI4JSwgODcuOTAxOTYwNzg0MyUpIiwibGFiZWxUZXh0Q29sb3IiOiJibGFjayIsImxvb3BUZXh0Q29sb3IiOiJibGFjayIsIm5vdGVCb3JkZXJDb2xvciI6IiNhYWFhMzMiLCJub3RlQmtnQ29sb3IiOiIjZmZmNWFkIiwibm90ZVRleHRDb2xvciI6ImJsYWNrIiwiYWN0aXZhdGlvbkJvcmRlckNvbG9yIjoiIzY2NiIsImFjdGl2YXRpb25Ca2dDb2xvciI6IiNmNGY0ZjQiLCJzZXF1ZW5jZU51bWJlckNvbG9yIjoid2hpdGUiLCJzZWN0aW9uQmtnQ29sb3IiOiJyZ2JhKDEwMiwgMTAyLCAyNTUsIDAuNDkpIiwiYWx0U2VjdGlvbkJrZ0NvbG9yIjoid2hpdGUiLCJzZWN0aW9uQmtnQ29sb3IyIjoiI2ZmZjQwMCIsInRhc2tCb3JkZXJDb2xvciI6IiM1MzRmYmMiLCJ0YXNrQmtnQ29sb3IiOiIjOGE5MGRkIiwidGFza1RleHRMaWdodENvbG9yIjoid2hpdGUiLCJ0YXNrVGV4dENvbG9yIjoid2hpdGUiLCJ0YXNrVGV4dERhcmtDb2xvciI6ImJsYWNrIiwidGFza1RleHRPdXRzaWRlQ29sb3IiOiJibGFjayIsInRhc2tUZXh0Q2xpY2thYmxlQ29sb3IiOiIjMDAzMTYzIiwiYWN0aXZlVGFza0JvcmRlckNvbG9yIjoiIzUzNGZiYyIsImFjdGl2ZVRhc2tCa2dDb2xvciI6IiNiZmM3ZmYiLCJncmlkQ29sb3IiOiJsaWdodGdyZXkiLCJkb25lVGFza0JrZ0NvbG9yIjoibGlnaHRncmV5IiwiZG9uZVRhc2tCb3JkZXJDb2xvciI6ImdyZXkiLCJjcml0Qm9yZGVyQ29sb3IiOiIjZmY4ODg4IiwiY3JpdEJrZ0NvbG9yIjoicmVkIiwidG9kYXlMaW5lQ29sb3IiOiJyZWQiLCJsYWJlbENvbG9yIjoiYmxhY2siLCJlcnJvckJrZ0NvbG9yIjoiIzU1MjIyMiIsImVycm9yVGV4dENvbG9yIjoiIzU1MjIyMiIsImNsYXNzVGV4dCI6IiMxMzEzMDAiLCJmaWxsVHlwZTAiOiIjRUNFQ0ZGIiwiZmlsbFR5cGUxIjoiI2ZmZmZkZSIsImZpbGxUeXBlMiI6ImhzbCgzMDQsIDEwMCUsIDk2LjI3NDUwOTgwMzklKSIsImZpbGxUeXBlMyI6ImhzbCgxMjQsIDEwMCUsIDkzLjUyOTQxMTc2NDclKSIsImZpbGxUeXBlNCI6ImhzbCgxNzYsIDEwMCUsIDk2LjI3NDUwOTgwMzklKSIsImZpbGxUeXBlNSI6ImhzbCgtNCwgMTAwJSwgOTMuNTI5NDExNzY0NyUpIiwiZmlsbFR5cGU2IjoiaHNsKDgsIDEwMCUsIDk2LjI3NDUwOTgwMzklKSIsImZpbGxUeXBlNyI6ImhzbCgxODgsIDEwMCUsIDkzLjUyOTQxMTc2NDclKSJ9fSwidXBkYXRlRWRpdG9yIjpmYWxzZX0) +# Examples +Read the [Getting Started](quickstart.md) for examples diff --git a/docs/examples/docker-compose.yml b/docs/examples/docker-compose.yml new file mode 100644 index 0000000..b34d1f4 --- /dev/null +++ b/docs/examples/docker-compose.yml @@ -0,0 +1,40 @@ +version: '3' +services: + opa: + image: mneil/opa-dynamodb + command: + - run + - --server + - --log-format=json-pretty + - --set=decision_logs.console=true + - --log-level=debug + - /quickstart/rbac.rego + environment: + ENDPOINT_URL: http://dynamodb:8000/ + # No need to change this. DynamoLocal doesn't verify authentication + AWS_REGION: us-east-1 + AWS_ACCESS_KEY_ID: foo + AWS_SECRET_ACCESS_KEY: bar + TABLE_NAME: OpaDynamoDB + ports: + - 8181:8181 + depends_on: + - dynamodb + links: + - dynamodb:dynamodb + volumes: + - .:/quickstart + dynamodb-admin: + image: aaronshaf/dynamodb-admin + environment: + DYNAMO_ENDPOINT: http://dynamodb:8000 + depends_on: + - dynamodb + ports: + - 8001:8001 + dynamodb: + image: amazon/dynamodb-local + command: -jar DynamoDBLocal.jar -sharedDb + ports: + - 9000:8000 + diff --git a/docs/examples/rbac.rego b/docs/examples/rbac.rego new file mode 100644 index 0000000..e99458a --- /dev/null +++ b/docs/examples/rbac.rego @@ -0,0 +1,24 @@ +package rbac + +# role-permissions assignments +role_permissions := { + "engineering": [{"action": "read", "object": "server123"}], + "webdev": [{"action": "read", "object": "server123"}, + {"action": "write", "object": "server123"}], + "hr": [{"action": "read", "object": "database456"}] +} + +# logic that implements RBAC. +default allow = false +allow { + # lookup the list of roles for the user + roles := dynamodb.policy("foo/bar", input.user) + # for each role in that list + r := roles[_] + # lookup the permissions list for role r + permissions := role_permissions[r] + # for each permission + p := permissions[_] + # check if the permission granted to r matches the user's request + p == {"action": input.action, "object": input.object} +} diff --git a/docs/images/table-creation.png b/docs/images/table-creation.png new file mode 100644 index 0000000000000000000000000000000000000000..d92b2df0d1cfc4c5c62d1a99cc39f95cfdd75462 GIT binary patch literal 18053 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 **WSL2 Users** may need to open on on the ipv6 address [http://[::1]:8001/](http://[::1]:8001/). See [this issue](https://github.com/microsoft/WSL/issues/4983) for more information + +?> _DynamoDB Admin_ is a GUI for exporing Dynamo data locally. It's not necessary to use this but it makes this example easier. + +Using the GUI, create a new table named `OpaDynamoDB`. This is the name of our table configured in the compose file. Set the Hash attribute to `PK` and the Range attribute to `SK`. + +![Table Creation](images/table-creation.png) + +Edit the table and add a policy to evaluate with our rego. Click create item and add two users with their roles: + +?> You have to add items individually right now in the GUI. So create one user, then repeat the process to create the next user. + +```json +{ + "PK": "foo/bar", + "SK": "alice", + "roles": ["engineering", "webdev"] +} +``` +```json +{ + "PK": "foo/bar", + "SK": "bob", + "roles": ["hr"] +} +``` + +Up to this point you have: + + - Defined a RBAC policy file + - Started a local DynamoDB Database + - Started OPA DynamoDB and connected to the database + - Filled the database with policy information + +Now you can query OPA to evaluate your policy file. The following query will check if user bob has the ability to read data on server123. + +```sh +curl -X POST http://localhost:8181/v1/data/rbac \ + -H "Content-Type: application/json" \ + --data '{"input":{"user":"bob","action":"read","object":"server123"}}' +``` From 6b48205eee5f019ceffbc9c64e74e91d4e00faf2 Mon Sep 17 00:00:00 2001 From: Michael Neil Date: Sun, 17 Jan 2021 12:35:00 -0800 Subject: [PATCH 07/11] Change ports to avoid conflicts when testing the example I want to be able to run the example from the docs and had some issues with port mappings in the dev container. --- .devcontainer/docker-compose.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml index ab125d1..514c230 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/docker-compose.yml @@ -13,8 +13,6 @@ services: AWS_ACCESS_KEY_ID: foo AWS_SECRET_ACCESS_KEY: bar TABLE_NAME: OpaDynamodbIntegrationTest - ports: - - 8001:8001 depends_on: - dynamodb links: @@ -23,5 +21,3 @@ services: dynamodb: image: amazon/dynamodb-local command: -jar DynamoDBLocal.jar -sharedDb - ports: - - 8000:8000 From c13025a890d3e2ada706e361e5e9372abc21e7c4 Mon Sep 17 00:00:00 2001 From: Michael Neil Date: Sun, 17 Jan 2021 14:24:26 -0800 Subject: [PATCH 08/11] Add example curl requests against the quick start --- docs/examples/rbac.rego | 14 ++++++++++---- docs/quickstart.md | 14 +++++++++++--- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/docs/examples/rbac.rego b/docs/examples/rbac.rego index e99458a..45f4b88 100644 --- a/docs/examples/rbac.rego +++ b/docs/examples/rbac.rego @@ -1,5 +1,12 @@ package rbac +# user-role assignments +# user_roles := dynamodb.policy("foo/bar", "alice") +# user_roles := { +# "alice": ["engineering", "webdev"], +# "bob": ["hr"] +# } + # role-permissions assignments role_permissions := { "engineering": [{"action": "read", "object": "server123"}], @@ -7,14 +14,13 @@ role_permissions := { {"action": "write", "object": "server123"}], "hr": [{"action": "read", "object": "database456"}] } - +# lookup the list of roles for the user +policy := dynamodb.policy(input.namespace, input.principal) # logic that implements RBAC. default allow = false allow { - # lookup the list of roles for the user - roles := dynamodb.policy("foo/bar", input.user) # for each role in that list - r := roles[_] + r := policy.roles[_] # lookup the permissions list for role r permissions := role_permissions[r] # for each permission diff --git a/docs/quickstart.md b/docs/quickstart.md index fad8eee..22b72da 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -55,7 +55,15 @@ Up to this point you have: Now you can query OPA to evaluate your policy file. The following query will check if user bob has the ability to read data on server123. ```sh -curl -X POST http://localhost:8181/v1/data/rbac \ - -H "Content-Type: application/json" \ - --data '{"input":{"user":"bob","action":"read","object":"server123"}}' +curl -X POST http://localhost:8181/v1/data/rbac/allow \ + -H "Content-Type: application/json" \ + --data '{"input":{"namespace":"foo/bar","principal":"bob","action":"read","object":"server123"}}' ``` + +You should receive a response similar to: + +```json +{"decision_id":"648eccb3-5d8b-4001-8a7a-9e87014ea36a","result":false} +``` + +Try changing the principal to alice instead and the result will be true. From f698e5a1d101141aa7c5c824b78894346b107b7d Mon Sep 17 00:00:00 2001 From: Michael Neil Date: Sun, 17 Jan 2021 14:39:12 -0800 Subject: [PATCH 09/11] Fix policy slice interface to value For now we only support a single item return in dynamo. It was possible to return a slice of data which was not correctly converted to a term. Tests were passing because we only had negative tests and the input for the test was not correctly serialized to JSON. I found this issue while trying to write getting started documentation and writing out a use case. --- policy/policy_test.go | 62 +++++++++++++++--------------- store/dynamodb.go | 10 +++-- store/dynamodb_test.go | 6 +-- testdata/attestors/rbac/authz.rego | 6 +-- 4 files changed, 41 insertions(+), 43 deletions(-) diff --git a/policy/policy_test.go b/policy/policy_test.go index 560d903..b7c9713 100644 --- a/policy/policy_test.go +++ b/policy/policy_test.go @@ -90,51 +90,44 @@ func TestPolicyDataIntegration(t *testing.T) { policy string principal string namespace string - data []map[string]string + action string + object string allow bool }{ { name: "rbac not allow bob", policy: "rbac/authz", - principal: "baz", + principal: "bob", namespace: "foo/bar", - data: []map[string]string{ - { - "user": "bob", - "action": "read", - "object": "server123", - }, - }, - allow: false, + action: "read", + object: "server123", + allow: false, }, { name: "rbac allow alice", policy: "rbac/authz", - principal: "baz", + principal: "alice", namespace: "foo/bar", - data: []map[string]string{ - { - "user": "alice", - "action": "read", - "object": "server123", - }, - }, - allow: false, + action: "read", + object: "server123", + allow: true, }, } // our actual tests is here in the loop for _, c := range cases { body, err := json.Marshal(struct { - Input interface{} + Input interface{} `json:"input"` }{ Input: struct { - principal string - namespace string - data []map[string]string + Principal string `json:"principal"` + Namespace string `json:"namespace"` + Action string `json:"action"` + Object string `json:"object"` }{ - principal: c.principal, - namespace: c.namespace, - data: c.data, + Principal: c.principal, + Namespace: c.namespace, + Action: c.action, + Object: c.object, }, }) resp, err := http.Post( @@ -146,13 +139,18 @@ func TestPolicyDataIntegration(t *testing.T) { defer resp.Body.Close() assert.Equal(t, http.StatusOK, resp.StatusCode, c.name) body, err = ioutil.ReadAll(resp.Body) - var v struct { - result struct { - allow bool - } - } + v := Response{} json.Unmarshal(body, &v) - assert.Equal(t, c.allow, v.result.allow, c.name) + fmt.Print("THE RESULT") + fmt.Print(string(body)) + assert.Equal(t, c.allow, v.Result.Allow, c.name) } +} + +type Result struct { + Allow bool `json:"allow"` +} +type Response struct { + Result Result `json:"result"` } diff --git a/store/dynamodb.go b/store/dynamodb.go index ef4d22b..cc198e3 100644 --- a/store/dynamodb.go +++ b/store/dynamodb.go @@ -63,6 +63,7 @@ func (dynamo *DynamoStore) Get(namespace string, principal string) (interface{}, KeyConditionExpression: aws.String("#PK = :pk AND #SK = :sk"), TableName: aws.String(dynamo.TableName), } + log.Debugf("Query input %v", input) result, err := dynamo.svc.Query(input) if err != nil { log.Error("Error querying data from dynamodb") @@ -73,13 +74,13 @@ func (dynamo *DynamoStore) Get(namespace string, principal string) (interface{}, } return "", err } + log.Debugf("Query result items %v", result.Items) itemLength := len(result.Items) if itemLength == 0 { log.Debug("No items returned from dynamodb") return "", nil } - log.Debugf("%d items returned from dynamodb", itemLength) - items := make([]map[string]interface{}, len(result.Items)) + items := make([]map[string]interface{}, itemLength) for index, item := range result.Items { var tmpItem map[string]interface{} dynamodbattribute.UnmarshalMap(item, &tmpItem) @@ -87,6 +88,7 @@ func (dynamo *DynamoStore) Get(namespace string, principal string) (interface{}, delete(tmpItem, dynamo.SortKey) items[index] = tmpItem } - log.Debugf("Policy from dynamodb %v", items) - return items, nil + log.Debugf("Policy from dynamodb %v", items[0]) + // There should only ever be one based on the query above + return items[0], nil } diff --git a/store/dynamodb_test.go b/store/dynamodb_test.go index 9f6fe4d..f6501d8 100644 --- a/store/dynamodb_test.go +++ b/store/dynamodb_test.go @@ -101,10 +101,8 @@ func TestGet(t *testing.T) { err: nil, namespace: "foo", principal: "bar", - expect: []map[string]interface{}{ - { - "foo": "bar", - }, + expect: map[string]interface{}{ + "foo": "bar", }, }, } diff --git a/testdata/attestors/rbac/authz.rego b/testdata/attestors/rbac/authz.rego index 5ea91b4..553e8b3 100644 --- a/testdata/attestors/rbac/authz.rego +++ b/testdata/attestors/rbac/authz.rego @@ -19,13 +19,13 @@ role_permissions := { default allow = false allow { # lookup the list of roles for the user - roles := dynamodb.policy("foo/bar", input.user) + policy := dynamodb.policy(input.namespace, input.principal) # for each role in that list - r := roles[_] + r := policy.roles[_] # lookup the permissions list for role r permissions := role_permissions[r] # for each permission p := permissions[_] # check if the permission granted to r matches the user's request p == {"action": input.action, "object": input.object} -} \ No newline at end of file +} From ac7e379452b9da430341b939d4a51c4b31c86392 Mon Sep 17 00:00:00 2001 From: Michael Neil Date: Sun, 17 Jan 2021 14:42:15 -0800 Subject: [PATCH 10/11] Add dynamo db admin to the dev container I needed that in order to debug some data during the integration tests. --- .devcontainer/docker-compose.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml index 514c230..a8ff356 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/docker-compose.yml @@ -18,6 +18,14 @@ services: links: - dynamodb:dynamodb command: tail -f /dev/null + dynamodb-admin: + image: aaronshaf/dynamodb-admin + environment: + DYNAMO_ENDPOINT: http://dynamodb:8000 + depends_on: + - dynamodb + ports: + - 8080:8001 dynamodb: image: amazon/dynamodb-local command: -jar DynamoDBLocal.jar -sharedDb From 3bc6bbc4c62e8df10293739db23fe4655f98f4d2 Mon Sep 17 00:00:00 2001 From: Michael Neil Date: Sun, 17 Jan 2021 14:49:26 -0800 Subject: [PATCH 11/11] Add default region and fake keys for test Now that the tests are actually correct I need to set fake keys and region for dynamodb local --- .github/workflows/test.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9780c07..86667d1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,5 +19,8 @@ jobs: uses: actions/checkout@v2 - name: Test env: + AWS_DEFAULT_REGION: us-east-1 + AWS_ACCESS_KEY_ID: foo + AWS_SECRET_ACCESS_KEY: bar ENDPOINT_URL: http://dynamodb:8000/ - run: make test \ No newline at end of file + run: make test