> ## Documentation Index
> Fetch the complete documentation index at: https://docs.railnet.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Guardrails

> How guardrails constrain what an asset manager can do within an Allocation Strategy — authorized sources, allocation caps, and RBAC

export const RbacDelegation = () => {
  const CSS = `
    .rb-bg{fill:#F8F8F8;rx:4;ry:4}.dark .rb-bg{fill:#141414}
    .rb-t{fill:#374151;font-family:"Inter Tight","Inter",system-ui,sans-serif}.dark .rb-t{fill:#D1D5DB}
    .rb-code{fill:#374151;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.dark .rb-code{fill:#D1D5DB}
    .rb-h{fill:#111827;font-family:"Inter Tight","Inter",system-ui,sans-serif}.dark .rb-h{fill:#E5E7EB}
    .rb-owner{fill:#FFE4D2;rx:3;ry:3}.dark .rb-owner{fill:#3D2510}
    .rb-am{fill:#D4E8E0;rx:3;ry:3}.dark .rb-am{fill:#1E3A2F}
  `;
  const ownerRoles = ['DEFAULT_ADMIN_ROLE', 'MULTI_VEHICLE_SET_VEHICLE_AUTH', 'FEE_MANAGER_SET_FEES', 'FEE_MANAGER_SET_FEE_RECIPIENTS'];
  const amRoles = ['MULTI_VEHICLE_DISPATCH', 'MULTI_VEHICLE_REBALANCE', 'MULTI_VEHICLE_MOVE_ASSETS', 'MULTI_VEHICLE_MOVE_SHARES', 'MULTI_VEHICLE_SET_QUEUES', 'MULTI_VEHICLE_PROGRESS_QUERY', 'MULTI_VEHICLE_FEED_QUERY_REDEEM_QUEUE', 'MULTI_VEHICLE_RETRIEVE_QUERY_REDEEM_QUEUE_ASSETS'];
  return <div className="not-prose w-full my-6 overflow-x-auto" style={{
    padding: '2px'
  }}>
      <style>{CSS}</style>
      <svg viewBox="0 -15 720 200" style={{
    width: '100%',
    height: 'auto',
    minWidth: '600px',
    display: 'block'
  }} role="img" aria-label="RBAC delegation model: owner roles versus asset manager roles">
        <rect x="0" y="-15" width="720" height="200" className="rb-bg" />

        <rect x="10" y="8" width="310" height="140" className="rb-owner" />
        <text x="30" y="30" className="rb-h" fontSize="12" fontWeight="700">Owner (platform)</text>
        {ownerRoles.map((role, i) => <text key={i} x="30" y={50 + i * 16} className="rb-code" fontSize="9.5">• {role}</text>)}
        <text x="30" y={50 + 4 * 16} className="rb-t" fontSize="10" fontStyle="italic">• Vehicle authorization</text>

        <rect x="345" y="8" width="365" height="170" className="rb-am" />
        <text x="365" y="30" className="rb-h" fontSize="12" fontWeight="700">Asset Manager (operator)</text>
        {amRoles.map((role, i) => <text key={i} x="365" y={50 + i * 16} className="rb-code" fontSize="9.5">• {role}</text>)}
      </svg>
    </div>;
};

<Info>In Railnet smart contracts, an Allocation Strategy is implemented as a **MultiVehicle**. See [Glossary](/developers/glossary) for all terminology.</Info>

<Tip>
  This page covers guardrails for Allocation Strategies, which use role-based access control via the External Access Control (EAC) contract. For Advanced Strategy guardrails, see [Policy engine](/strategies/advanced/policy-engine).
</Tip>

Guardrails define the trust boundary between the party that owns an Allocation Strategy (typically the platform deploying the Conduit) and the asset manager who operates it day-to-day. The owner sets the rules. The asset manager executes within them.

## The delegation model

The owner retains admin control while granting the asset manager scoped operational roles. The asset manager can execute the strategy within the boundaries the owner defines — they cannot change the rules.

<RbacDelegation />

## What the owner controls

These controls remain exclusively with the Allocation Strategy owner and form the guardrails:

| Guardrail                    | Role (retained by owner)                  | Why                                                        |
| ---------------------------- | ----------------------------------------- | ---------------------------------------------------------- |
| **Authorized yield sources** | `MULTI_VEHICLE_SET_VEHICLE_AUTHORIZATION` | The owner decides which yield sources the strategy can use |
| **Fee rates**                | `FEE_MANAGER_SET_FEES`                    | The owner controls the economics                           |
| **Fee recipients**           | `FEE_MANAGER_SET_FEE_RECIPIENTS`          | The owner controls revenue distribution                    |
| **Role assignments**         | `DEFAULT_ADMIN_ROLE`                      | The owner controls who has access                          |
| **Infrastructure upgrades**  | `BEACON_UPGRADE`                          | The owner controls contract upgrades                       |

The asset manager operates within these boundaries. They can allocate capital, rebalance positions, and manage queues — but they cannot authorize new yield sources, change fees, or grant roles to others.

## Grant operational roles

Grant the asset manager scoped roles on the appropriate contracts. All Allocation Strategy operational roles are scoped to the **Sector Accounting Engine**, except queue management (scoped to the **Queue Strategy Engine**) and query progression roles.

<CodeGroup>
  ```solidity Solidity theme={null}
  address am = 0x...; // Asset manager address
  ISectorAccountingEngine accounting = MultiVehicle(multiVehicle).accountingEngine();
  IQueueStrategyEngine strategy = accounting.strategyEngine();
  ISubQueryEngine subQueryEngine = accounting.subQueryEngine();

  // Core operational roles (scoped to Sector Accounting Engine)
  eac.grantScopedRole(keccak256("MULTI_VEHICLE_DISPATCH"), address(accounting), am);
  eac.grantScopedRole(keccak256("MULTI_VEHICLE_REBALANCE"), address(accounting), am);
  eac.grantScopedRole(keccak256("MULTI_VEHICLE_MOVE_ASSETS"), address(accounting), am);
  eac.grantScopedRole(keccak256("MULTI_VEHICLE_MOVE_SHARES"), address(accounting), am);

  // Queue management (scoped to Queue Strategy Engine)
  eac.grantScopedRole(keccak256("MULTI_VEHICLE_SET_QUEUES"), address(strategy), am);

  // Query progression (scoped to Sub Query Engine)
  eac.grantScopedRole(keccak256("MULTI_VEHICLE_PROGRESS_QUERY"), address(subQueryEngine), am);

  // Redemption queue (scoped to Multi-Vehicle)
  eac.grantScopedRole(keccak256("MULTI_VEHICLE_FEED_QUERY_REDEEM_QUEUE"), address(multiVehicle), am);
  eac.grantScopedRole(keccak256("MULTI_VEHICLE_RETRIEVE_QUERY_REDEEM_QUEUE_ASSETS"), address(multiVehicle), am);
  ```

  ```typescript TypeScript theme={null}
  // Coming soon
  ```
</CodeGroup>

<Warning>
  Always verify the **scope** parameter matches the correct contract. Granting a role with the wrong scope will not authorize the intended operation.
</Warning>

## What the asset manager can do

With the roles above, the asset manager can:

| Operation                        | Role                                               | Scope                    |
| -------------------------------- | -------------------------------------------------- | ------------------------ |
| Move assets between sectors      | `MULTI_VEHICLE_MOVE_ASSETS`                        | Sector Accounting Engine |
| Move shares between sectors      | `MULTI_VEHICLE_MOVE_SHARES`                        | Sector Accounting Engine |
| Dispatch assets to yield sources | `MULTI_VEHICLE_DISPATCH`                           | Sector Accounting Engine |
| Rebalance between yield sources  | `MULTI_VEHICLE_REBALANCE`                          | Sector Accounting Engine |
| Configure allocation queues      | `MULTI_VEHICLE_SET_QUEUES`                         | Queue Strategy Engine    |
| Progress sub-queries             | `MULTI_VEHICLE_PROGRESS_QUERY`                     | Sub Query Engine         |
| Feed the redemption queue        | `MULTI_VEHICLE_FEED_QUERY_REDEEM_QUEUE`            | MultiVehicle             |
| Retrieve redemption queue assets | `MULTI_VEHICLE_RETRIEVE_QUERY_REDEEM_QUEUE_ASSETS` | MultiVehicle             |

## Optional: grant fee collection roles

You may want the asset manager (or a keeper) to handle routine fee collection:

<CodeGroup>
  ```solidity Solidity theme={null}
  // Allow the AM to trigger fee distribution (but NOT change fee rates or recipients)
  eac.grantScopedRole(keccak256("FEE_MANAGER_DISPATCH_ERC20"), address(feeManager), am);
  eac.grantScopedRole(keccak256("FEE_MANAGER_REDEEM_VEHICLE_SHARES"), address(feeManager), am);
  ```

  ```typescript TypeScript theme={null}
  // Coming soon
  ```
</CodeGroup>

## Monitor your asset manager

Track your Allocation Strategy's performance and the asset manager's operations via the Railnet subgraph:

```graphql theme={null}
query MultiVehicleStatus($address: String!) {
  Vehicle(where: { address: { _ilike: $address } }) {
    supply
    SectorBalance {
      asset
      value
      sector { name }
    }
    Query(order_by: { createdAt: desc }, limit: 20) {
      mode
      state
      createdAt
    }
  }
}
```

See [Reporting](/developers/api) for comprehensive monitoring queries and dashboards.

## Revoke access

To offboard an asset manager, revoke all scoped roles. Pending operations will complete, but the asset manager cannot initiate new ones.

<CodeGroup>
  ```solidity Solidity theme={null}
  address am = 0x...; // Asset manager to offboard

  // Revoke all operational roles
  eac.revokeScopedRole(keccak256("MULTI_VEHICLE_DISPATCH"), address(accounting), am);
  eac.revokeScopedRole(keccak256("MULTI_VEHICLE_REBALANCE"), address(accounting), am);
  eac.revokeScopedRole(keccak256("MULTI_VEHICLE_MOVE_ASSETS"), address(accounting), am);
  eac.revokeScopedRole(keccak256("MULTI_VEHICLE_MOVE_SHARES"), address(accounting), am);
  eac.revokeScopedRole(keccak256("MULTI_VEHICLE_SET_QUEUES"), address(strategy), am);
  eac.revokeScopedRole(keccak256("MULTI_VEHICLE_PROGRESS_QUERY"), address(subQueryEngine), am);
  eac.revokeScopedRole(keccak256("MULTI_VEHICLE_FEED_QUERY_REDEEM_QUEUE"), address(multiVehicle), am);
  eac.revokeScopedRole(keccak256("MULTI_VEHICLE_RETRIEVE_QUERY_REDEEM_QUEUE_ASSETS"), address(multiVehicle), am);

  // Revoke fee collection roles if granted
  eac.revokeScopedRole(keccak256("FEE_MANAGER_DISPATCH_ERC20"), address(feeManager), am);
  eac.revokeScopedRole(keccak256("FEE_MANAGER_REDEEM_VEHICLE_SHARES"), address(feeManager), am);
  ```

  ```typescript TypeScript theme={null}
  // Coming soon
  ```
</CodeGroup>

<Tip>
  Before offboarding, ensure there are no in-progress queries that require the asset manager's roles to complete. Check the query state via the subgraph.
</Tip>

## Next steps

<CardGroup cols={2}>
  <Card title="Operate an Allocation Strategy" icon="sliders" href="/strategies/allocation/operate">
    Manage allocations, rebalance across yield sources, and handle operations.
  </Card>

  <Card title="Roles and permissions" icon="shield-halved" href="/developers/contracts/roles">
    Complete guide to role setup, scoping, and common permission patterns.
  </Card>
</CardGroup>
