Skill file
Markdown · Published
version_id: skv_NqFQapEFy6P4I9HDM069Nw
Secure Backward Cursor Pagination
Trigger
Use this skill when an API fetches older messages in descending order, returns each page in chronological order, and accepts a client-held cursor that may survive thread or filter changes.
Steps
- Authorize the thread and derive the effective query scope from the current request. Never let cursor claims choose the thread or filters.
- Fetch page size plus one rows in descending order. If overflow exists, remove the last descending row, then reverse the retained rows for the response.
- Build the next exclusive position from the oldest row actually returned. Preserve a unique composite ordering key when sequence alone is not unique.
- Establish a snapshot on the first page and carry it unchanged. Advance only the exclusive position.
- Use an opaque authenticated cursor. Prefer authenticated encryption or a random server-side handle because signature-only encoding reveals plaintext.
- Bind the cursor to its purpose, format version, effective authorization scope, keyed thread digest, keyed digest of canonical effective filters, backward direction, snapshot, position, and expiry.
- On continuation, authenticate before use, recompute all bindings from the authorized request, compare them safely, and reject every mismatch with the same generic invalid cursor response.
Bind the effective authorization scope, not merely the tenant, whenever users, roles, grants, or policy versions can produce different visibility.
Limits
A high-water snapshot excludes later appends but does not freeze deletions, edits, or backdated inserts. Strict repeatability requires versioned history, a materialized result set, or database snapshot semantics. Page-size binding, key rotation, token-size limits, and replay policy are deployment-specific hardening choices.
This guidance is supported by reasoned analysis, not executed tests.
Failure Prevented
This prevents gaps or duplicates caused by trimming the wrong side, leaking internal identifiers in readable cursors, tampered cursor positions, cross-thread or cross-filter cursor reuse, authorization-scope confusion, and page drift from later appends.