Code Monkey home page Code Monkey logo

opa-aws-cloudformation-hook's Introduction

OPA AWS CloudFormation Hook

OPA AWS CloudFormation Hook Diagram

This repository integrates AWS CloudFormation (CFN) with OPA using AWS Cloud Formation Hooks. Use this integration if you want to enforce policies over AWS resources (e.g., EC2 instances, S3 buckets, etc.) provisioned with CloudFormation. For example, using this integration you can enforce policy across resources like:

AWS Cloud Formation Hooks were added in February 2022. The feature is still relatively new for AWS Cloud Formation. If you run into any issues please report them here.

How it Works

The OPA hook works by installing an AWS CloudFormation Hook to your environment.

When creating, updating, or deleting a CloudFormation Stack, the hook is triggered to validate the configuration. When used in conjunction with OPA, the hook will send the property information from each resource in a Stack to your OPA server. When this information is received, OPA will validate the request against your defined policies and send back any violations it may have found, which will stop the stack creation and log the violations to AWS CloudWatch. If no violations are reported, the resources contained in the stack are created, updated or deleted accordingly.

NOTE: Installing OPA into your AWS environment is currently out of scope for this documentation. For local development, a tool like ngrok could be used to point at an OPA running on your machine.

Want to try out this integration yourself? See the AWS Cloud Formation Hooks tutorial in the OPA documentation.

Repository Contents

Provided in this repository, you'll find the code for the hook you'll deploy in your AWS account to enable OPA policy enforcement for your CloudFormation resources under the hooks directory. See the OPA tutorial on the topic for instructions on how to quickly get started, or the development guide in AWS the documentation if you'd like to learn more about how it works.

To give you an idea about what policy for AWS CloudFormation Hooks might look like, this repository provides a number of example resources and policies:

  • The examples/templates directory contains example templates used for testing
  • The examples/policy directory contains example policies

Policy Development

In order to quickly iterate on changes in your Rego policies, you may use the validate.py tool provided under the test directory. The tool allows you to test your policies against provided CloudFormation template files, without actually submitting them to a hook installed in your environment. With an OPA server started with your policy files loaded (e.g. opa run --server --watch examples/policy), you may use the tool like:

test/validate.py my-cloudformation-template.yaml

The tool will extract all resources found in the template and submit them to OPA one by one, in the same manner the hook operates once installed. Should any violation be encountered, the tool will print them to the console.

Deregistering the Hook

Deregistering a hook requires removal of not just the hook type, but also any versions of the hook deployed. In order to help with that, you may use the deregister-hook.sh script provided in this repo, with the ARN of the hook provided as the only argument:

./deregister-hook.sh <ARN of your hook here>

Community

For questions, discussions and announcements related to Styra products, services and open source projects, please join the Styra community on Slack!

opa-aws-cloudformation-hook's People

Contributors

anderseknert avatar charlieegan3 avatar dependabot[bot] avatar jordanhoeft avatar pauly4it avatar peteroneilljr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

opa-aws-cloudformation-hook's Issues

Run integration tests as part of the build

It would be nice if we could run the integration tests as part of the build as well. These tests would need to:

  1. Start OPA pointed at the policy directory.
  2. Run ./test-templates.py (which we'll need to modify to exit with an error code on test failures).
  3. Stop OPA (optional I guess for GH actions, but nice to be able to run this locally as well).

AWS Secrets Manager Bearer Token Value Parsing

Does the AWS Secrets Manager bearer token value need parsing? Your code:

https://github.com/StyraInc/opa-aws-cloudformation-hook/blob/main/hooks/src/styra_opa_hook/handlers.py#L28-L44

Returns the SecretString from SecretsManager: {"opa_auth_token": "<VALUE>"}.

Are you expecting that entire string {"opa_auth_token": "<VALUE>"} to be configured in the OPA sever token auth? Or do we need to parse the actual value out with something like:

`if 'SecretString' in resp:
    return list(json.loads(resp['SecretString']).values())[0]`

Automate fetching of all resource types to add to styra-opa-hook.json

While we can add these manually to styra-opa-hook.json during development as we add more and more resource type example policies, we'll want to list all resource types available for AWS Cloudformation before we publish this hook to the marketplace. The reason for this is that we'll want to keep the hook as generic as possible, and have the user determine whether something is allowed or not in policy rather than configuration.

Ideally, I think we'll have a script run nightly (or whatever interval seems appropriate) to fetch the resource definitions from the AWS API and make sure we're up to date. If we aren't we should create a PR and later on a release from that (this part could be done manually).

Separate example policies from the main (i.e. router) policy

Users of this hook likely will want to provide their own policies rather than the examples we provide. I think we should move these to a new examples directory where we can have one subdirectory for the templates (as suggested by @tsandall elsewhere), and another for policy.

Remaining in the policy directory should only be main.rego and authz.rego, plus a subdirectory for the tests / helpers.

Allow JSON template files

While YAML files definitely are easier on the eye, JSON is also a supported format, and we should allow that. While this makes no difference to the policy, we should modify the template test runner to allow for this, as that might be what some users provide.

Publish hook to AWS Marketplace

Having the user install the hook themselves works pretty well, but it would be nice if we also offered this hook directly in the AWS Marketplace. This would also help with discoverability.

Rewrite test-templates.py to work on provided file or directory

The script currently reads the templates directory for all templates, and submits them to OPA for validation one by one.

It would be a great improvement if we instead allowed the user to point the tool at either a single template, or a directory. This would allow them to use the same tool for their own policy authoring, where they'd run OPA locally, and submitted templates converted to JSON to OPA, and have the script return the output. Suggested steps, but these are very much just some ideas:

  • Rename to validate.py (or whatever is appropriate)
  • Allow argument to point out single template, or directory, which will be submitted to OPA (localhost:8181 hardcoding is fine).
  • By default, we shouldn't "test" the returned response but rather just print it to the console, nicely formatted.
  • When provided a --test flag or similar, we do what we currently do and print FAIL, SUCCESS, and so on.
  • Add some docs to explain what the tool does and how to use it.

handlers.py: Exception caught sequence item 0: expected str instance, dict found

After setting up the CloudFormation hook and creating a stack with an S3 bucket with public access, the following was logged to CloudWatch for the hook:

Exception caught sequence item 0: expected str instance, dict found
Traceback (most recent call last):
  File "/var/task/cloudformation_cli_python_lib/hook.py", line 273, in __call__
    raise error
  File "/var/task/cloudformation_cli_python_lib/hook.py", line 262, in __call__
    caller_sess, request, invocation_point, callback, type_configuration
  File "/var/task/cloudformation_cli_python_lib/hook.py", line 100, in _invoke_handler
    return handler(session, request, callback_context, type_configuration)
  File "/var/task/styra_opa_hook/handlers.py", line 127, in pre_handler
    return opa_query(request, session, type_configuration, action)
  File "/var/task/styra_opa_hook/handlers.py", line 97, in opa_query
    message = " | ".join(body["violations"])
TypeError: sequence item 0: expected str instance, dict found

For reference, the OPA agent returned the following:

{"allow":false,"violations":[{"allowed":false,"message":"public access not blocked for bucket testing"}]}

Non-Linux users without Docker Desktop cannot build hook locally

For users who do not have Docker Desktop installed locally due to licensing issues, the cfn submit command cannot be run with the default Docker flow. Disabling the Docker option in the hook configuration and building the zip file on a non-Linux system results in Lambda function errors. The cfn cli does not currently officially support Docker alternatives.

I recommend running the cfn submit --dry-run command on an Ubuntu GitHub runner with Docker installed to generate a valid hook zip file.

Decide on best way to run OPA for docs

While ngrok works great for local testing, we'll not want to depend on a proprietary third-party service for the OPA docs. It would be good if we, as part of the docs, set up OPA either running as a container in something like ECS, or as a Lambda. We'll also want to run this so that it uses the management APIs like how we do it in the other tutorials.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.