# Identity and permissions

Go inputs, results, permissions and executable examples for identity and permissions.

Use this reference with the [complete developer tour](https://beepgrid.com/docs/sdks/go/tour.md) and [Go types](https://beepgrid.com/docs/sdks/go/types.md). The example at the end runs after the tour setup.

## SaveContactPermissions

Save the subject's dedicated contact defaults and exceptions atomically.

```text
func (c *Client) SaveContactPermissions(ctx context.Context, in ContactPermissionsInput) (map[string]any, error)
```

| Parameter | Type and default | Usage |
| --- | --- | --- |
| `ctx` | `context.Context` (required) | Required Go context. Cancellation bounds this local call; it does not withdraw a durable request. |
| `in` | `ContactPermissionsInput` (required) | Typed operation input. Every field is listed in the language types reference. |

**Returns:** The saved policy and its new version.

**Permissions, lifecycle and errors:** Use the observed version and preserve deny effects. Explicit blocks override other matching grants; omission restores defaults.

[Working Go example](https://beepgrid.com/docs/sdks/go/identity/#example). Input/output fields are in the [types reference](https://beepgrid.com/docs/sdks/go/types.md).

## Example

Run this region after [the shared setup](https://beepgrid.com/docs/sdks/go/tour.md). Assertions check the returned data; the full tour is a runnable program.



```go
subject := beepgrid.Target{Kind: "agent", ID: builderID}
contactPreview := must(owner.PreviewContactPermissions(ctx, beepgrid.ContactPreviewInput{Subject: subject}))
contactVersion := int64(contactPreview["policy"].(map[string]any)["version"].(float64))
contactPolicy := must(owner.SaveContactPermissions(ctx, beepgrid.ContactPermissionsInput{Subject: subject, Version: contactVersion,
	Rules: []beepgrid.PermissionRule{{Action: "view", TargetKind: "agent", TargetID: billingID}}}))
check(int64(contactPolicy["version"].(float64)) > contactVersion)
```
