Dev.to Security πŸ” Cybersecurity πŸ‘ 0 πŸ“– 8 min read

Media Offboarding Order: Revoke Before Delete Without Losing Billing Attribution

Revoke access before deleting a media tenant, and preserve the attribution records needed to reconcile accepted platform events before purging the tenant's operational rows. The deciding constraint is billing accuracy du

Revoke access before deleting a media tenant, and preserve the attribution records needed to reconcile accepted platform events before purging the tenant's operational rows. The deciding constraint is billing accuracy during an outage: removing an account must not erase the evidence needed to determine which tenant owned an event when the backend accepted it.

TL;DR: close admission, revoke credentials, reconcile previously accepted events, then delete eligible tenant data. Keep an offboarding control record until verification finishes. Deleting first can remove the identifiers needed to revoke credentials or explain orphan rows; revoking first still needs a separate barrier against background work that can recreate them.

This is a proposed runbook for a media backend receiving platform events, not a report of a measured production incident. Its security baseline comes from the OWASP Secrets Management Cheat Sheet, which treats revocation, expiration, auditing, and destruction as parts of the secret lifecycle. The billing and recovery controls below are design recommendations for applying that lifecycle to tenant offboarding.

What page fired when the tenant disappeared?

Start a postmortem with the page and its evidence. An account disappearing from an administrative dashboard proves little about credential acceptance, pending events, or attribution in the billing ledger, especially when the backend responsible for showing that status is also experiencing an outage. A green deletion counter is a weak reason to close an incident.

Ask what failed.

For this design, define two independently actionable conditions: an event accepted after the tenant's admission barrier, and an accepted event that cannot be assigned to its original billing identity. The first calls for investigating authorization and event admission; the second calls for suspending the affected billing finalization while attribution is reconciled. These are proposed alert conditions, not claims about any platform's existing monitoring. Route them to owners who can inspect the underlying records, and include the offboarding operation identifier so the page leads somewhere useful.

Consider a synthetic test fixture with 12 accepted media events for tenant media_demo, of which 3 remain pending when offboarding begins. Those counts are test inputs. The required outcome is that each accepted event has one explicit disposition under the billing policy, including each pending event; a deletion acknowledgment says nothing about that result. If a consumer later retries one of those events, it must not create a second charge or reconstruct the deleted tenant as a side effect.

That is the incident boundary: access has ended, but accounting for work already accepted has not necessarily ended.

Should tenant offboarding revoke access first or delete rows first?

Treat revoke-then-delete and delete-then-revoke as dependency questions. In a design where credential lookup depends on the tenant row, deleting that row first can strand the revocation job without its target identifiers. In a design where removing an account also authoritatively invalidates every associated credential, deletion may include revocation, but that property needs explicit evidence and a test covering outstanding credentials. An account deletion label alone does not establish it.

The proposed default is revoke first because its verification can run while the necessary account and credential references still exist. That order introduces a deliberate pause between ending access and completing data removal. The trade-off is extra retained state and reconciliation work in exchange for recoverable billing evidence. This approach is not suitable for a deletion policy that prohibits retaining the proposed attribution fields; choose a policy-approved accounting representation before deploying it. Define retention and deletion obligations before adopting it; this runbook supplies no universal retention duration.

Separate three kinds of identity in the design. The operational tenant record supports active service. A credential reference identifies authority that must be retired. An attribution reference identifies the tenant and billing context associated with an already accepted event. Avoid retaining a usable secret merely because its reference is needed for the offboarding audit. OWASP's lifecycle guidance is relevant here: audit evidence and secret material have different purposes.

Don't improvise a new billing owner when an old lookup fails.

An accepted event should carry, or resolve through a protected record to, the attribution identity chosen at admission. Specify which billing context must remain reproducible under your accounting policy, and limit the retained fields accordingly. Keeping an entire account profile indefinitely because one event needs reconciliation is an unexamined retention decision, not a recovery strategy.

Execute the shutdown as a recoverable state machine

Create a durable offboarding operation before changing authority. Give it an operation identifier, a tenant reference, an admission barrier, and separately recorded completion evidence for credential revocation, event reconciliation, and data deletion. These are proposed application fields, not an external API contract. Make phase transitions conditional on the expected prior state so that retries resume the same operation instead of starting an unrelated cleanup.

The admission barrier is the crucial implementation detail. Define it in the same consistency boundary used to decide whether an event can enter the accepted workload, and make every relevant ingress path honor it. A UI flag checked by one request handler is insufficient for a design with another ingestion path or an asynchronous consumer that can create tenant-owned records. If a path cannot enforce the barrier, the operation must remain incomplete until that path is fenced or its access is removed and verified.

Use this sequence as the implementation contract:

Phase Required evidence before advancing Failure behavior
Close admission New work cannot enter the tenant's accepted workload through relevant paths Keep the operation pending and investigate any admitted event
Revoke authority Known credential references are retired and previously valid credentials fail the defined access check Retry revocation while preserving the references needed to finish
Reconcile accepted work Each accepted event has a billing disposition, including quarantined exceptions Hold affected billing finalization and preserve attribution
Delete eligible data Remaining operational dependencies are resolved under the deletion policy Resume cleanup from recorded progress

Revocation failure must block the destructive phase. Preserve enough information to retry it without preserving usable credentials in logs. Record the outcome and the identity of the operation; OWASP's auditing guidance supports tracing lifecycle actions, but it does not require copying secret values into that trace.

Reconciliation deserves more care than a queue-depth chart. Specify an authoritative set of accepted events, then compare its event identities with completed or explicitly held billing dispositions. In the synthetic fixture, all 12 identities must be accounted for; reaching zero pending messages is not the acceptance criterion. A consumer might have acknowledged a message before the billing disposition became durable in a flawed implementation. Test that boundary directly instead of assuming a quiet dashboard means the ledger is complete.

For duplicate delivery, use a stable event identity and enforce the intended uniqueness rule where the billing disposition is committed. Define that rule precisely: separate legitimate events must remain distinguishable, while redelivery of the same accepted event must not create another disposition. A retry mechanism without that distinction can turn outage recovery into an attribution problem.

Finally, remove operational rows in an order consistent with the actual dependency model. Where referential constraints exist, use their behavior deliberately and verify it; where dependencies live outside that boundary, inventory and check them explicitly. Retain the minimum offboarding control and attribution records required by the applicable policies. Removing the last operational row is a cleanup milestone, not permission to discard unfinished evidence.

Verify the outage boundary before deployment

Use the same synthetic fixture to stop execution after each phase boundary, restart it, and compare the resulting attribution and access decisions. Include a revocation failure, a delayed consumer, a duplicate accepted event, and a cleanup retry. Also submit an event after the admission barrier: the test must establish that it never joins the accepted workload. These are failure injections to implement, not reported test results.

Test the destructive alternative too. Remove the operational tenant row before attempting revocation in an isolated fixture, then determine whether the implementation can still locate every credential reference and account for all accepted events. This reveals the real dependency more effectively than arguing over the names of two buttons. If the application claims deletion already invalidates authority, this is where that claim has to survive credential checks and recovery after interruption.

For orphan rows, define what counts as an orphan before writing a cleanup query. A retained attribution record with an intentional reference to a retired billing identity is different from an operational child row whose required parent vanished. Check each according to its intended lifetime. Counting both as garbage could make an orphan cleanup erase the very billing evidence the runbook is meant to preserve.

Deploy with a bounded cohort selected for inspectable dependencies. Review per-operation evidence before widening that cohort, and decide in advance who can halt cleanup when attribution diverges. The extra control records and reconciliation work consume storage and engineering time; their justification is a recoverable, explainable billing result. Capacity planning should follow accepted-event volume, unresolved work, and retention policy, rather than a promise that offboarding is just one database operation.

Roll back execution without restoring access

On a failed rollout, pause destructive workers and preserve the admission barrier while investigating the recorded phase. A rollback that restores a previous application binary must still honor operations already in progress. Include that compatibility requirement in the deployment check, because an older ingress path that ignores the barrier would undermine the shutdown even if the new cleanup worker has stopped.

Keep access closed.

Do not automatically reactivate retired credentials to make reconciliation easier. Recovery of accepted work should use a separately authorized internal path with an auditable scope, and any business decision to restore tenant service should follow a new authorization decision. Once data has been deleted, reversing a state label does not restore it; plan recovery according to the data actually retained and the applicable deletion policy.

Close the operation only when the evidence supports three separate conclusions: authority is retired, accepted work remains correctly attributable, and eligible operational dependencies have been removed. For a media backend, that is the useful answer to revoke versus delete order. Revoke before delete by default, preserve the evidence needed to finish, and page on violations of those boundaries instead of trusting an account status panel.

References

πŸ“° Read the original article on Dev.to Security

Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes β€” full credit and traffic to the original publisher.