skip to content

A RESTCONF POST adds a permit entry to an ordered-by-user ACL after its deny-all entry; how do insert and point fix the order?

level: middleimportance: should knowfreq 8%

answer

  1. the user owns the order
  2. the default position is the end
  3. first, last, before, after
  4. point names the neighbour by path

basics

~20 s

RESTCONF's insert parameter defaults to last, so the new entry landed behind deny-all and never matches. insert=before with point set to the deny-all entry's path places it ahead; both work only on POST and PUT into ordered-by-user lists or leaf-lists.

solid answer

~40 s

The ACE list in `ietf-access-control-list` is `ordered-by user`, so the server keeps whatever order the client gives it, and a POST without `insert` uses the default, `last` — behind the catch-all deny, where it can never match. RFC 8040 §4.8.5 defines `insert=first|last|before|after`; `before` and `after` need a `point` parameter naming the existing entry by its resource path, percent-encoded, such as `/ietf-access-control-list:acls/acl=edge-in/aces/ace=deny-all`. Send `before` or `after` without `point`, or `point` without them, and the server returns `400 Bad Request`. Both parameters are mandatory to implement, work only with POST and PUT, and only on a list or leaf-list declared `ordered-by user`; a PUT with them can also move an existing entry.

code

http · 9 lines
http
POST /restconf/data/ietf-access-control-list:acls/acl=edge-in/aces?insert=first HTTP/1.1
Host: core1.example.net
Content-Type: application/yang-data+json

{"ietf-access-control-list:ace": [{"name": "deny-bogons",
  "actions": {"forwarding": "ietf-access-control-list:drop"}}]}

HTTP/1.1 201 Created
Location: https://core1.example.net/restconf/data/ietf-access-control-list:acls/acl=edge-in/aces/ace=deny-bogons

go deeper

for a junior

Recall that some YANG lists are ordered by the user, and that RESTCONF appends new entries at the end unless told otherwise.

for a middle

Explain insert's four values, when point is required, how point names the neighbour, and which methods and lists accept them.

for a senior

Prevent shadowed security rules: always state insert, anchor on named neighbours, verify order after the change, and move entries with PUT.

for a principal

Weigh positional edits against whole-list replacement or YANG Patch for rule-set changes, considering atomicity, audit trails and concurrent writers.

## Why order is the client's problem here YANG lets a module say who owns the order of a list (RFC 7950 §7.7.7): - **`ordered-by system`** (the default) — the server may order entries however it likes; their order carries no meaning. - **`ordered-by user`** — the order is meaningful, the user controls it and the server must keep it. Packet filters are the textbook case — RFC 7950 itself motivates the statement with a filter whose discard-all-TCP entry must be placed deliberately before or after an entry that permits trusted interfaces. In the `ietf-access-control-list` module (RFC 8519) the `ace` list inside each ACL is declared `ordered-by user`, because entries are evaluated in sequence and the first match decides. ## What went wrong An ACL `edge-in` ends with an entry named `deny-all`. Automation adds `permit-ntp` with a `POST` to the parent `aces` container. RESTCONF's **`insert`** parameter (RFC 8040 §4.8.5) defaults to **`last`**, so the new entry was appended after `deny-all`. The configuration is syntactically perfect, the server answered `201 Created`, and the rule can never match. ## The two parameters | `insert` value | Effect | Needs `point`? | |---|---|---| | `first` | new first entry | no | | `last` | new last entry (the default) | no | | `before` | immediately before the entry named by `point` | yes | | `after` | immediately after the entry named by `point` | yes | The **`point`** parameter (§4.8.6) identifies the insertion point by its path, in the same format as a target resource URI — module-qualified first node, list keys after `=` — and, like any query value, with reserved characters percent-encoded. ```http POST /restconf/data/ietf-access-control-list:acls/acl=edge-in/aces?insert=before&point=%2Fietf-access-control-list%3Aacls%2Facl%3Dedge-in%2Faces%2Face%3Ddeny-all HTTP/1.1 Host: core1.example.net Content-Type: application/yang-data+json {"ietf-access-control-list:ace": [{"name": "permit-ntp", "actions": {"forwarding": "ietf-access-control-list:accept"}}]} HTTP/1.1 201 Created Location: https://core1.example.net/restconf/data/ietf-access-control-list:acls/acl=edge-in/aces/ace=permit-ntp ``` (The match conditions are omitted for brevity; the `forwarding` identity is from RFC 8519.) ## The rules the server enforces 1. `insert` and `point` are allowed only with **`POST` and `PUT`**, and only when the target is a data resource whose list or leaf-list is **`ordered-by user`**. 2. `insert=before` or `insert=after` without `point` returns **`400 Bad Request`**. 3. `point` without `insert`, or with `insert=first` or `last`, also returns **`400 Bad Request`**. 4. Both parameters **MUST be supported** by every server — they have no capability URI, unlike `depth`, `fields` or `with-defaults`. 5. For a `POST`, the target is the parent and the new entry travels in the body; for a `PUT`, the target is the entry itself. `point` names a resource "being created or moved", so a `PUT` with `insert` and `point` can also reposition an existing entry. ## Operating it safely - **Never rely on the default for a security list.** Write `insert` explicitly on every create, even when `last` is what you want; it documents intent in the request log. - **Anchor on names, not positions.** `point` names a neighbour by its key, so the request means the same thing however many entries precede it. - **Read back the order.** A `GET` on the `aces` container returns entries in the user order the server maintains, so a post-change check can confirm the new entry sits before the catch-all. - **Know the alternative.** Reordering several entries in one atomic edit is the job of a YANG Patch, a separate media type with its own insert and move operations, not of these query parameters. ## Why not rewrite the whole list? A client could instead `PUT` the entire `aces` container with the entries in the right order. That is atomic and simple to reason about, but: - the request carries every entry, so a one-rule change becomes a full-list write; - another writer's change made between the client's read and its `PUT` is overwritten unless the client uses entity-tag preconditions; - the audit log shows a replacement, not the single intended insertion. A positional `POST` with `insert` and `point` touches one entry and names its anchor, which is usually what change review wants to see. ## Summary On a user-ordered list, `last` is the silent default; `before` and `after` need a `point`; both parameters live on POST and PUT, are mandatory to implement, and are rejected anywhere the order is not the user's to set.

  • What does a RESTCONF server do with insert=first on a list declared ordered-by system?
    It rejects it. RFC 8040 allows `insert` and `point` only when the target list or leaf-list is `ordered-by user`; under `ordered-by system` the server owns the order and the client has no position to request.
  • How do you move an existing ACE ahead of deny-all without deleting and re-creating it?
    Send a `PUT` to the entry's own URI with `insert=before` and `point` naming the `deny-all` entry. §4.8.6 describes `point` for an entry being created or moved, and PUT supports both parameters on user-ordered data. The body must still carry the full entry, because PUT replaces it.

saying these in an interview costs you the question

  • Without insert, the server places the new entry first.
  • point alone is enough to place an entry before another.
  • insert and point work on any list, whatever its ordered-by statement.
  • insert is optional and must be found in the capability list.
  • PATCH with insert reorders entries in a plain merge.