# Quickstart

Create a directory to store the policies.

```sh
mkdir -p cerbos-quickstart/policies
```

Now start the Cerbos server. We are using the container image in this guide but you can follow along using the binary as well. See [installation instructions](https://docs.cerbos.dev/cerbos/latest/installation/binary) for more information.

```shell
docker run --rm --name cerbos -d -v $(pwd)/cerbos-quickstart/policies:/policies -p 3592:3592 -p 3593:3593  ghcr.io/cerbos/cerbos:0.53.0
```

Time to try out a simple request.

|     |     |
| --- | --- |
|  | If you prefer to use [Postman](https://www.postman.com/), [Insomnia](https://insomnia.rest/) or any other software that supports OpenAPI, you can follow this guide along on those tools by downloading the OpenAPI definitions from [http://localhost:3592/schema/swagger.json](http://localhost:3592/schema/swagger.json). You can also use the built-in API browser by pointing your browser to [http://localhost:3592](http://localhost:3592/). |

- cURL
- .NET
- Go
- Java
- JS
- PHP
- Python
- Ruby
- Rust

```shell
cat <<EOF | curl --silent "http://localhost:3592/api/check/resources?pretty" -d @-
{
  "requestId": "quickstart",
  "principal": {
    "id": "bugs_bunny",
    "roles": [\
      "user"\\
    ],
    "attr": {
      "beta_tester": true
    }
  },
  "resources": [\
    {\
      "actions": [\
        "view:public",\
        "comment"\
      ],\
      "resource": {\
        "kind": "album:object",\
        "id": "BUGS001",\
        "attr": {\
          "owner": "bugs_bunny",\
          "public": false,\
          "flagged": false\
        }\
      }\
    },\
    {\
      "actions": [\
        "view:public",\
        "comment"\
      ],\
      "resource": {\
        "kind": "album:object",\
        "id": "DAFFY002",\
        "attr": {\
          "owner": "daffy_duck",\
          "public": true,\
          "flagged": false\
        }\
      }\
    }\
  ]
}
EOF
```

```json
{
  "requestId": "quickstart",
  "results": [\
    {\
      "resource": {\
        "id": "BUGS001",\
        "kind": "album:object"\
      },\
      "actions": {\
        "comment": "EFFECT_DENY",\
        "view:public": "EFFECT_DENY"\
      }\
    },\
    {\
      "resource": {\
        "id": "DAFFY002",\
        "kind": "album:object"\
      },\
      "actions": {\
        "comment": "EFFECT_DENY",\
        "view:public": "EFFECT_DENY"\
      }\
    }\
  ]
}
```

In this example, the `bugs_bunny` principal is trying to perform two actions (`view:public` and `comment`) on two `album:object` resources.

This is the response from the server:

Now create a [derived roles](https://docs.cerbos.dev/cerbos/latest/policies/derived_roles) definition that assigns the `owner` dynamic role to a user if the `owner` attribute of the resource they’re trying to access is equal to their ID.

```sh
cat > cerbos-quickstart/policies/derived_roles_common.yaml <<EOF
---
apiVersion: "api.cerbos.dev/v1"
derivedRoles:
  name: common_roles
  definitions:
    - name: owner
      parentRoles: ["user"]
      condition:
        match:
          expr: request.resource.attr.owner == request.principal.id
EOF
```

Also create a resource policy that gives `owner`s full access to their own albums.

```sh
cat > cerbos-quickstart/policies/resource_album.yaml <<EOF
---
apiVersion: api.cerbos.dev/v1
resourcePolicy:
  version: "default"
  importDerivedRoles:
    - common_roles
  resource: "album:object"
  rules:
    - actions: ['*']
      effect: EFFECT_ALLOW
      derivedRoles:
        - owner
EOF
```

Try the request again. This time `bugs_bunny` should be allowed access to his own album but denied access to the album owned by `daffy_duck`.

Response

```json
{
  "requestId": "quickstart",
  "results": [\
    {\
      "resource": {\
        "id": "BUGS001",\
        "kind": "album:object"\
      },\
      "actions": {\
        "comment": "EFFECT_ALLOW",\
        "view:public": "EFFECT_ALLOW"\
      }\
    },\
    {\
      "resource": {\
        "id": "DAFFY002",\
        "kind": "album:object"\
      },\
      "actions": {\
        "comment": "EFFECT_DENY",\
        "view:public": "EFFECT_ALLOW"\
      }\
    }\
  ]
}
```

Now add a rule to the policy to allow users to view public albums.

```sh
cat > cerbos-quickstart/policies/resource_album.yaml <<EOF
---
apiVersion: api.cerbos.dev/v1
resourcePolicy:
  version: "default"
  importDerivedRoles:
    - common_roles
  resource: "album:object"
  rules:
    - actions: ['*']
      effect: EFFECT_ALLOW
      derivedRoles:
        - owner

- actions: ['view:public']
      effect: EFFECT_ALLOW
      roles:
        - user
      condition:
        match:
          expr: request.resource.attr.public == true
EOF
```

If you try the request again, `bugs_bunny` now has `view:public` access to the album owned by `daffy_duck` but not `comment` access. Can you figure out how to update the policy to give him `comment` access as well?

Once you are done experimenting, the Cerbos server can be stopped with the following command:

```shell
docker kill cerbos
```

Next steps
- [Explore the demo apps built with Cerbos](https://github.com/cerbos?q=demo&type=all&language=&sort=)
- [Read more about Cerbos policies](https://docs.cerbos.dev/cerbos/latest/policies/)
- [Join the Cerbos community on Slack](http://go.cerbos.io/slack)
- [Ask us anything via](mailto:help@cerbos.dev) [help@cerbos.dev](mailto:help@cerbos.dev)
