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?
answer
- the user owns the order
- the default position is the end
- first, last, before, after
- point names the neighbour by path
basics
~20 sRESTCONF'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 sThe 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 linesPOST /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-bogonsgo deeper
Recall that some YANG lists are ordered by the user, and that RESTCONF appends new entries at the end unless told otherwise.
Explain insert's four values, when point is required, how point names the neighbour, and which methods and lists accept them.
Prevent shadowed security rules: always state insert, anchor on named neighbours, verify order after the change, and move entries with PUT.
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.