This repository contains source code of the Go implementation of the Cedar policy language.
Cedar is a language for writing and enforcing authorization policies in your applications. Using Cedar, you can write policies that specify your applications' fine-grained permissions. Your applications then authorize access requests by calling Cedar's authorization engine. Because Cedar policies are separate from application code, they can be independently authored, updated, analyzed, and audited. You can use Cedar's validator to check that Cedar policies are consistent with a declared schema which defines your application's authorization model.
Cedar is:
Cedar is a simple yet expressive language that is purpose-built to support authorization use cases for common authorization models such as RBAC and ABAC.
Cedar is fast and scalable. The policy structure is designed to be indexed for quick retrieval and to support fast and scalable real-time evaluation, with bounded latency.
Cedar is designed for analysis using Automated Reasoning. This enables analyzer tools capable of optimizing your policies and proving that your security model is what you believe it is.
Cedar can be used in your application by importing the github.com/cedar-policy/cedar-go
package.
The Go implementation includes:
The Go implementation does not yet include:
Here's a simple example of using Cedar in Go:
package main
import (
"encoding/json"
"fmt"
"log"
cedar "github.com/cedar-policy/cedar-go"
)
const policyCedar = `permit (
principal == User::"alice",
action == Action::"view",
resource in Album::"jane_vacation"
);
`
const entitiesJSON = `[
{
"uid": { "type": "User", "id": "alice" },
"attrs": { "age": 18 },
"parents": []
},
{
"uid": { "type": "Photo", "id": "VacationPhoto94.jpg" },
"attrs": {},
"parents": [{ "type": "Album", "id": "jane_vacation" }]
}
]`
func main() {
var policy cedar.Policy
if err := policy.UnmarshalCedar([]byte(policyCedar)); err != nil {
log.Fatal(err)
}
ps := cedar.NewPolicySet()
ps.Add("policy0", &policy)
var entities cedar.EntityMap
if err := json.Unmarshal([]byte(entitiesJSON), &entities); err != nil {
log.Fatal(err)
}
req := cedar.Request{
Principal: cedar.NewEntityUID("User", "alice"),
Action: cedar.NewEntityUID("Action", "view"),
Resource: cedar.NewEntityUID("Photo", "VacationPhoto94.jpg"),
Context: cedar.NewRecord(cedar.RecordMap{
"demoRequest": cedar.True,
}),
}
ok, _ := ps.IsAuthorized(entities, req)
fmt.Println(ok)
}
CLI output:
allow
This request is allowed because VacationPhoto94.jpg
belongs to Album::"jane_vacation"
, and alice
can view photos in Album::"jane_vacation"
.
If you'd like to see more details on what can be expressed as Cedar policies, see the documentation.
The cedar-go module houses four public packages:
General documentation for Cedar is available at docs.cedarpolicy.com, with source code in the cedar-policy/cedar-docs repository.
Generated documentation for the latest version of the Go implementation can be accessed here.
If you're looking to integrate Cedar into a production system, please be sure the read the security best practices
x/exp - code in this directory is not subject to the semantic version constraints of the rest of the module and breaking changes may be made at any time
Parents
field on types.Entity
has been changed to an immutable set type with an interface similar to types.Set
UnsafeDecimal()
constructor for the types.Decimal
type has been removed and replaced with the following safe constructors, which return error on overflow:
NewDecimal(int64 i, int exponent) (Decimal, error)
NewDecimalFromInt[T constraints.Signed](i T) (Decimal, error)
NewDecimalFromFloat[T constraints.Float](f T) (Decimal, error)
Value
field on types.Decimal
has been made private. Instances of Decimal
can be compared with one another via the new Compare
method.types.DecimalPrecision
has been made privatetypes.ErrDateitme
, types.ErrDecimal
, types.ErrDuration
, types.ErrIP
, types.ErrNotComparable
types.FromStdTime()
has been renamed to types.NewDatetime()
types.DatetimeFromMillis()
has been renamed to types.NewDatetimeFromMillis()
types.FromStdDuration()
has been renamed to types.NewDuration()
types.DurationFromMillis()
has been renamed to types.NewDurationFromMillis()
types.Entities
has been renamed to types.EntityMap
types.Entity
is now immutable, types.EntityMap
now stores items by value rather than by pointerPolicySet.Store()
has been renamed to PolicySet.Add()
PolicySet.Delete()
has been renamed to PolicySet.Remove()
types.Set()
now takes variadic arguments of type types.Value
instead of a single []types.Value
argumenttypes.Set
is now implemented as a hash set, turning Set.Contains()
into an O(1) operation, on average. This mitigates a worst case quadratic runtime for the evaluation of the containsAny()
operator.types
package are now exported via the cedar
package as well.types.Set
is now an immutable type which must be constructed via types.NewSet()
Set.Iterate()
, which takes an iterator callback.Set
s, so they won't be rendered when calling Set.MarshalCedar()
or Set.MarshalJSON
.types.Value
are now safe to copy shallowly, so Set.DeepClone()
has been removed.types.Record
is now an immutable type which must be constructed via types.NewRecord()
Record.Iterate()
, which takes an iterator callback.types.Value
are now safe to copy shallowly, so Record.DeepClone()
has been removed.datetime
and duration
extension types specified in RFC 80.
x/exp/batch
ast
package.cedar
package to the types
package.strings
, previously they were numeric.PolicyID
form.NewPolicySet
then
parse individual files using NewPolicyListFromBytes
and subsequently use
PolicySet.Store
to add each of the policy statements.Entity
and Entities
types have moved from the cedar
package to the types
package.Value
method Cedar() string
was changed to MarshalCedar() []byte
See CONTRIBUTING for more information.
We welcome contributions from the community. Please either file an issue, or see CONTRIBUTING
This project is licensed under the Apache-2.0 License.