An approval was corrected to Declined: how to test permission revocation

Xây dựng tích hợp trong sandbox miễn phí trước khi chuẩn bị môi trường sản xuất.

Lựa chọn thống kê của bạn được dùng lại trên website và có thể tắt. Liên kết tài khoản cần đồng ý riêng.

An approval was corrected to Declined: how to test permission revocation

Your fixture session received Approved and granted a local permission. A later event says Declined. You need to decide whether that event revokes access, and how to tell a real correction from a replayed or stale callback. This article tests that decision in the synthetic fixture and separates what the fixture does from what your application must design.

Bài này hiện bằng tiếng Anh; bản dịch đang chờ cập nhật.

curl https://gridzen.ai/console/api/quickstart/trial \
  -H 'Content-Type: application/json' \
  -d '{"task": "identity_onboarding", "scenario": "success"}'

Hướng dẫn tích hợp

The problem: an approval that no longer holds

A seller passed verification, your handler recorded Approved, and the explicit policy allowed a local permission. Later a new Declined event arrives for the same session. If your code treats every terminal status as final, it ignores the correction and access stays open. If it treats every incoming event as fresh, a replayed callback can flip state back and forth. The goal is narrow. A new Declined correction after Approved must set permission_granted from true to false. grant_count must stay at 1, because the history of the grant does not disappear. Duplicate and stale events must change nothing. Whether a real provider ever sends such corrections, and what they mean, depends on that provider's actual contract. The fixture only lets you rehearse the shape.

What the fixture actually implements

The downloadable identity example stores sessions and processed event IDs in SQLite. Its event method accepts only mode synthetic_fixture and source fixture_callback, and only event IDs that start with fixture-. It has no production signature verifier. It checks tenant and subject binding first, then deduplicates on the session and event ID pair. One rule handles corrections. If the stored status is approved and the incoming status is Declined, the fixture records the event and sets status to declined and granted to 0. It leaves the grants counter untouched. Any other event against an approved, declined or expired session returns the current state unchanged. That event is not recorded either. This correction check runs before the deadline check, so a Declined correction after Approved is applied even when it arrives after the deadline. live_permission_changed is always false. No real permission exists.

Hypothetical scenario and expected outputs

This is a hypothetical walkthrough on fixture-session, bound to fixture-tenant and fixture-user, with deadline 60. Step 1: send event fixture-approved with status Approved and policy true. Expect status approved, deadline 60, permission_granted true, grant_count 1, live_permission_changed false. Step 2: replay fixture-approved. Expect the identical object. The duplicate is a no-op. Step 3: send a new event ID, for example fixture-correction, with status Declined. Expect status declined, deadline 60, permission_granted false, grant_count 1, live_permission_changed false. The tested expired output is a different path: a session that never received an approval. It has status expired, permission_granted false, grant_count 0, next review_or_authorized_provider_refresh and provider_polled false. Do not use it as evidence of revocation.

New correction, duplicate, or stale pending event

Three inputs can look alike and must stay distinct. A new correction carries an unseen event ID and status Declined against an approved session. It revokes the permission. A duplicate reuses a processed event ID. It returns stored state, even if its status field now differs. A stale pending event, such as In Progress or In Review arriving after Approved, must not downgrade or re-grant anything. The fixture returns current state and does not record it. Two more cases follow the same rule. A late Approved after a Declined correction is also ignored, so permission does not silently reopen. A second Declined after declined changes nothing. Test each case with distinct event IDs and assert both permission_granted and grant_count.

Proposed design: a caller-owned revocation receipt

The following is a proposed design, not fixture behavior. The fixture flips one flag; real revocation touches listings, payouts or sessions in systems you own. A caller-owned revocation receipt could record: - the session - the correcting event ID - the previous and new status - the grant count at revocation - a timestamp - which downstream actions were requested and confirmed Write the receipt in the same transaction that clears the permission. Make downstream undo steps idempotent against that receipt. Before trusting a correction, re-fetch the authoritative decision through an authorized provider route. A synthetic Declined is not evidence of a real decline, and synthetic fixture permission is not live business permission.

Failure handling

Several failures need defined behavior. If a correction fails the binding check, the fixture raises BINDING_MISMATCH. Treat this as an alert, not as a revocation. Non-synthetic sources raise PRODUCTION_SIGNATURE_VERIFIER_NOT_IMPLEMENTED. Event IDs without the fixture- prefix raise SYNTHETIC_EVENT_REQUIRED. Sending an event for an unknown session raises BINDING_MISMATCH; reading an unknown session with read raises SESSION_NOT_FOUND. The recover method only expires pending, review or unknown sessions locally. It never polls a provider and never reverses an approval. Do not rely on it to catch a missed correction. If your downstream revocation partially fails, keep the permission cleared and mark the receipt incomplete for review. Do not restore access.

Acceptance checklist

- Approved with policy true yields permission_granted true and grant_count 1. - A replayed approval event ID leaves both fields unchanged. - A new Declined event yields status declined, permission_granted false and grant_count 1. - Stale In Progress or In Review after Approved changes nothing. - A late Approved after the correction does not restore permission. - A correction with the wrong tenant or subject is rejected. - live_permission_changed stays false throughout. - Your own receipt and downstream undo steps are tested separately. - Your correction semantics are confirmed against the real provider contract before any live use.

Run the checked synthetic example

Download and extract https://gridzen.ai/downloads/verification-delivery.zip, enter verification_delivery, then run with Python 3.10+. This local example makes no network calls. Use a fresh database for an independent identity run.

python3 delivery.py identity --db /tmp/gridzen-article-fixture.sqlite

Sources and scope

https://gridzen.ai/guides/approved-seller-permissions/ https://gridzen.ai/guides/current-capabilities/ Based on the checked source snapshot and local fixture; proposed application rules are design advice, not proven production behavior. Written with AI assistance and reviewed independently.

Thử riêng ba kết quả sandbox Tạo tài khoản để tiếp tục tích hợp

Tải xuống không chứng minh đã chạy thành công. Ví dụ cục bộ và sandbox trực tuyến được thử riêng.

Kết nối ứng dụng

Chạy ba kết quả dữ liệu mẫu · Nhận hỗ trợ tích hợp

Kết nối tài khoản sandbox miễn phí

Tính hợp lệ cơ bản của số không chứng minh quyền kiểm soát hay khả năng liên lạc và không gửi OTP. Ứng dụng của bạn chịu trách nhiệm quyết định tiếp nhận.