Integrate OPA to allow making `advisories` more complex, custom
The key issue right now is working out how this should work with "always sync the state to the DB" (and avoiding requirement to always use dmd
or dmd-web
, while trying to make the extra expressiveness of the policies work better.
Maybe:
- New table,
policy_violations
which includes:-
platform
, etc, through todep_types
-
- Advisories
JOIN
onpolicy_violations
, and produce the rows that match, for each Datasource
I.e. Mend's policies, Dependency Track's policies
https://www.openpolicyagent.org/docs/latest/integration/#integrating-with-the-go-api
i.e.
# one of:
dmd report policies
dmd policy evaluate
Plus in the web app, if there is a policies
directory
Give the ability to:
- Define an
advisory_type
,is_advisory
- Define a
description
- Define an
is_allowed
?
package main
import (
"context"
"fmt"
"log"
"github.com/open-policy-agent/opa/rego"
)
func main() {
module := `
package example.authz
import future.keywords.if
import future.keywords.in
default allow := false
default is_admin := false
default type := "SECURITY"
allow if {
input.method == "GET"
input.path == ["salary", input.subject.user]
}
allow if is_admin
is_admin if "admin" in input.subject.groups
`
ctx := context.TODO()
query, err := rego.New(
rego.Query(`x = data.example.authz.allow
is_admin=data.example.authz.is_admin
type=data.example.authz.type
`),
rego.Module("example.rego", module),
).PrepareForEval(ctx)
if err != nil {
log.Fatal(err)
}
input := map[string]interface{}{
"method": "GET",
"path": []interface{}{"salary", "bob"},
"subject": map[string]interface{}{
"user": "bob",
"groups": []interface{}{"sales", "marketing"},
},
}
results, err := query.Eval(ctx, rego.EvalInput(input))
if err != nil {
log.Fatal(err)
}
if err != nil {
log.Fatal(err)
} else if len(results) == 0 {
// Handle undefined result.
fmt.Printf("results: %v\n", results)
} else if result, ok := results[0].Bindings["x"].(bool); !ok {
fmt.Printf("result: %v\n", result)
// Handle unexpected result type.
} else {
// Handle result/decision.
fmt.Printf("%v\n", results)
fmt.Printf("%+v\n", results)
fmt.Printf("%#v\n", results)
}
}
Edited by Jamie Tanna