Home

Awesome

opa-lambda-extension-plugin

A custom plugin for running Open Policy Agent (OPA) in AWS Lambda as a Lambda Extension.

To learn more about how Lambda Extensions work, check out these AWS docs, which provide a helpful graphic depicting the Lambda lifecycle.

Usage

This project provides an OPA plugin that integrates OPA with the Lambda Extension API. To use this plugin, you must compile a custom version of the OPA binary. Instructions to do this are available in OPA's documentation. In the future, we hope to contribute/release changes that provide a simpler experience, similar to the opa-envoy-plugin project.

This plugin can be tricky to implement, depending on whether or not you use the OPA discovery plugin.

Usage without Discovery

If you don't need to use the discovery plugin, then you don't need to make many changes in your custom OPA compilation. Just modify main.go to import the plugin module (see snippet just below). If you're unfamiliar with custom plugins in OPA, check out the OPA docs on the subject.

// Copyright 2016 The OPA Authors.  All rights reserved.
// Use of this source code is governed by an Apache2
// license that can be found in the LICENSE file.

package main

import (
  "fmt"
  "os"

  // Import the plugin so that it can register itself with the OPA runtime on init
  _ "github.com/godaddy/opa-lambda-extension-plugin/plugins/lambda"

  "github.com/open-policy-agent/opa/cmd"
)

func main() {
  if err := cmd.RootCommand.Execute(); err != nil {
    fmt.Println(err)
    os.Exit(1)
  }
}

// Capabilities file generation:
//go:generate build/gen-run-go.sh internal/cmd/genopacapabilities/main.go capabilities.json

// WASM base binary generation:
//go:generate build/gen-run-go.sh internal/cmd/genopawasm/main.go -o internal/compiler/wasm/opa/opa.go internal/compiler/wasm/opa/opa.wasm  internal/compiler/wasm/opa/callgraph.csv

Everything else can be wired up in OPA configuration. Note the trigger: manual on the bundles, decision_logs, and status plugins.

services:
  acmecorp:
    url: https://example.com/control-plane-api/v1

bundles:
  authz:
    service: acmecorp
    resource: bundles/http/example/authz.tar.gz
    polling:
      trigger: manual
      scope: write

decision_logs:
  service: acmecorp
  reporting:
    trigger: manual

status:
  service: acmecorp
  trigger: manual

plugins:
  lambda_extension:
    minimum_trigger_threshold: 30
    trigger_timeout: 7
    plugin_start_priority:
      - bundle
      - decision_logs
      - status
    plugin_stop_priority:
      - decision_logs
      - status
      - bundle

Usage with Discovery

The discovery plugin prevents other plugins from being registered in the bootstrap configuration. This prevents the lambda extension plugin from being registered via configuration, because the lambda extension plugin must run before the discovery plugin. To use the lambda extension plugin with discovery, you must compile a custom OPA binary wherein you register the lambda extension plugin directly with the runtime, e.g.

lambdaPluginFactory := lambda.PluginFactory{}
rt.Manager.Register(lambda.Name, lambdaPluginFactory.New(rt.Manager, nil))

This is less than ideal and the complexity involved with this implementation is outside the scope of this document. For now, just know that if you really need to implement both the discovery and lambda extension plugins, it is possible to do so. In the future, we hope to contribute/release changes that make this implementation simpler.

Configuration

plugins:
  lambda_extension:
    # The number of seconds that must elapse before plugins will be triggered by a lambda function invocation
    minimum_trigger_threshold: 30
    # The number of seconds that ALL plugins have to complete their trigger before they are canceled.
    trigger_timeout: 7
    # The order in which plugins will be started while the Lambda Extension is in its init phase.
    plugin_start_priority:
      - bundle
      - decision_logs
      - status
    # The order in which plugins will be stopped while the Lambda Extension is in its shutdown phase.
    plugin_stop_priority:
      - decision_logs
      - status
      - bundle

Development

make fmt

make lint

make test

More Information

The plugin is heavily commented with useful information.