Agent Wranglers

Permissions, flags and failures Recommended

Let the server say what each user may do

Send the actions the user may take on each record with the record, and show controls from that list. Never rebuild the permission rules in the client.

How to do it

Add a field such as "allowedActions": ["edit", "send"] to each record, computed by the same code that enforces access. The screen shows a control only when its action is listed. Hide actions the user can never take. Show actions they could take after a change, such as a plan upgrade, with the reason.

Example

def invoice_json(invoice: Invoice, user: User) -> dict:
    return {
        "id": invoice.id,
        "number": invoice.number,
        "status": invoice.status,
        "allowedActions": [action for action in ("edit", "send", "delete") if policy.allows(user, action, invoice)],
    }
export function InvoiceActions({ invoice }: { invoice: Invoice }) {
  const can = (action: InvoiceAction) => invoice.allowedActions.includes(action);
  return (
    <div className="invoice-actions">
      {can('edit') && <LinkButton href={`/invoices/${invoice.id}/edit`}>Edit</LinkButton>}
      {can('send') && <SendButton invoice={invoice} />}
      {can('delete') && <DeleteButton invoice={invoice} />}
    </div>
  );
}

How to check

Search the client for role names, such as 'admin' or role ===. There are no matches outside the sign-in code.

For agents: if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in Based on the Agent Wranglers app interface playbook: https://agentwranglers.se/playbook/app-ui/permissions-flags-and-failures/capabilities-from-server.