/cedar-agent-go-sdk

Go SDK for Cedar Agent 🌲

Primary LanguageGoMIT LicenseMIT

cedar-agent-go-sdk

GoReportCard example GoDoc reference example version Code Climate maintainability

Cedar Agent is an HTTP Server that runs the Cedar authorization engine.

It's the easiest way to get up and running with Cedar locally, offering a REST API for managing your entities and policies, as well as policy evaluation.

Cedar lets you answer the question: Is this user (principal) allowed to perform this action on this resource?

Installation

go get -u github.com/kevinmichaelchen/cedar-agent-go-sdk

Usage

Creating a client

package main

import (
	"github.com/kevinmichaelchen/cedar-agent-go-sdk/sdk"
	"net/http"
)

func initClient() *sdk.Client {
	c := &http.Client{}

	// The options are entirely ... optional 🙂
	return sdk.NewClient(c,
		sdk.WithBaseURL("http://localhost:8180"),
		sdk.WithParallelizationFactor(3),
	)
}

Performing authorization checks

package main

import (
	"context"
	"fmt"
	"github.com/kevinmichaelchen/cedar-agent-go-sdk/sdk"
	"net/http"
)

func main() {
	ctx := context.Background()
	client := initClient()
	allowed := isAuthorized(ctx, client,
		sdk.CheckRequest{
			Principal: `User::"42"`,
			Action: "viewFoobar",
			Resource: `Foobar::"101"`,
		},
	)
	fmt.Printf("allowed: %t", allowed)
}

func isAuthorized(ctx context.Context, client *sdk.Client, r sdk.CheckRequest) bool {
	res, err := client.Check(ctx, r)
	if err != nil {
		panic(err)
	}
	return res.Allowed
}

Authorizing a batch

Sometimes you want to authorize a principal against multiple resources, potentially with multiple actions.

package main

import (
	"context"
	"fmt"
	"github.com/kevinmichaelchen/cedar-agent-go-sdk/sdk"
	"net/http"
)

func main() {
	ctx := context.Background()
	client := initClient()

	principal := `User::"42"`

	requests := map[sdk.Action][]sdk.Resource{
		"viewFoo": {
			`Foo::"12"`,
			`Foo::"39"`,
			`Foo::"72"`,
		},
		"viewBar": {
			`Bar::"12"`,
		},
	}

	out, err := client.CheckBatch(ctx, principal, requests, 5)
	if err != nil {
		panic(err)
	}

	for req, decision := range out {
		fmt.Printf("request: %v, decision: %t", req, decision.Allowed)
	}
}