---
title: "RecommendAgentPolicy"
description: "Recommend a least-privilege policy from recorded traffic"
canonical: "https://pgbeam.com/docs/go-sdk/policies/recommendAgentPolicy"
last-updated: "2026-09-09T11:37:53.000Z"
---

# RecommendAgentPolicy

> Recommend a least-privilege policy from recorded traffic

URL: https://pgbeam.com/docs/go-sdk/policies/recommendAgentPolicy

Derives the tightest policy that would still pass every statement this agent credential has legitimately run, using its recorded audit history over a lookback window (default 30 days). The candidate's table allowlist is the union of relations actually referenced, its statement-kind allow set is the observed set, it downgrades to read-only when no writes were seen, and its max\_rows ceiling comes from an observed high-percentile row count. The candidate is proven safe by replaying it through the data plane's own policy engine against the same history: a good recommendation has replay.summary.newly\_blocked == 0. This endpoint is advisory only. It reads the audit log, never connects to the upstream database, and never creates, updates, or mutates any policy or credential; the operator loads the candidate into the editor and saves it themselves.

## Usage

## Parameters

Parameter

Type

Required

Description

ctx

`context.Context`

Yes

Request context

projectID

`string`

Yes

Unique project identifier (prefixed, e.g. prj\_xxx).

agentID

`string`

Yes

Unique agent credential identifier (prefixed, e.g. agt\_xxx).

req

`pgbeam.PolicyRecommendationInput`

Yes

Request body

req.LookbackDays

`*int`

No

How many days of recorded audit history to analyze.

req.Limit

`*int`

No

Maximum number of distinct query shapes to analyze and replay, newest first. Traffic is deduplicated by normalized query hash.

## Response

`(*pgbeam.PolicyRecommendation, error)`: the recommended candidate policy and its replay proof.

## Example

## Errors

Status

Description

400

The request was rejected. `code` is `INVALID_INPUT`, and `errors` names the offending fields when the failure was a validation one.

401

Missing or invalid authentication. `code` is `UNAUTHORIZED`.

403

The caller is authenticated but not allowed to perform this operation. `code` is `FORBIDDEN` when the caller's role is insufficient, and `PLAN_LIMIT_REACHED` when the organization's plan is what stands in the way. The two are answered differently, so branch on the code rather than the status.

404

The resource does not exist, or the caller is not entitled to know that it does. `code` is `NOT_FOUND`.

413

The request body exceeds the 2 MB limit. `code` is `PAYLOAD_TOO_LARGE`.

415

The request body is not JSON, or carries a body without declaring a Content-Type. `code` is `UNSUPPORTED_MEDIA_TYPE`.

429

Rate limited. `code` is `RATE_LIMITED`.

500

The request failed for a reason on our side. `code` is `INTERNAL_ERROR`. Quote `request_id` when reporting it.