Give the customer a verifiable outcome
A customer closing a SaaS workspace needs to know what data they received, what the package excludes and what happens after access ends. A download button covers only the transfer step. Product acceptance must also cover a consistent cutoff, readable relationships, delivery to an authorized recipient and a clear closure state.
Consider a fictional workspace with records and attachments. The proposed outcome is a package the customer can inspect before the agreed closure step, plus a receipt identifying the exported snapshot. This article supplies a tiny verified package fixture and an unexecuted acceptance brief. It does not report a customer migration or prescribe a retention period.
Define the unit of closure first. Closing one user's login, ending a subscription and closing a tenant workspace are different operations. A person who leaves one workspace may still belong to another. The product should name the object affected before requesting a consequential decision.
Decide what the export promises
Write the export scope in the customer's terms, then map it to data objects. Include attachments and relationships needed to interpret the records. State deliberate exclusions, such as credentials or data classes covered by a separate export process. A package can be internally consistent and still fail the customer's task if its scope was never agreed.
The proposed acceptance brief separates the decisions so an owner can provide evidence for each one:
| Decision | Proposed owner | Acceptance evidence |
|---|---|---|
| Scope and cutoff | Product owner | Included objects, exclusions and treatment of later writes |
| Authority to close and receive | Security owner | Authorized tenant decision maker and current recipient access |
| Package contract | Engineering owner | Version, identifiers, counts, checksums and resolved references |
| Customer verification | Customer and support | Readable sample, accepted handoff or documented missing content |
| Access closure | Operations owner | Sessions, credentials, jobs and file access reach intended states |
| Retained data | Data owner | Existing approved policy mapped to each data class |
| Failure handling | Support owner | Defined retry, expiry and incomplete-closure actions |
Download the handoff acceptance CSV to adapt these rows. Every result is marked not executed and every evidence field is empty. Assign actual owners before treating the brief as a release gate.
The cutoff deserves its own decision. A preview export may use a snapshot while normal writes continue. A final closing export needs either a controlled write freeze or a defined final delta. Otherwise, changes made after the snapshot can disappear from the customer's handoff without appearing as an error in the export job.
Make completeness inspectable
An export manifest should identify the package version, tenant scope and snapshot cutoff. For each payload file, record its path, byte length and checksum. Include record counts and the conventions required to read the data: encoding, delimiter, identifier meaning and how attachments are referenced. A stable record ID is more useful for reconstruction than a row's position in a spreadsheet.
The fictional ZIP fixture contains two records, one text attachment and a manifest. Its manifest is also available separately. The record CSV points to the attachment by a package-relative path. Record r2 has no attachment. For this example, the manifest explicitly excludes credentials, billing records and the audit log.
The accompanying package constructor and checks can be saved as package_example.py and run with Python 3 in an empty working directory. It creates the fictional package and check results. The complete fixture passes. Removing its attachment fails the inventory check, and changing the attachment bytes fails the payload check. These checks establish the example's integrity rules, not the completeness of an export from a live database.
RFC 8493's BagIt format provides a useful distinction between having the required files and verifying their checksums. The fixture uses a custom JSON contract and does not claim BagIt conformance. Checksums detect a mismatch with the manifest. If someone can replace both manifest and payload, hashes alone do not establish origin or authorization.
Business completeness needs another comparison: reconcile exported objects against the selected source snapshot and agreed scope. A missing source object will not be detected by a perfectly matching checksum for every file that happened to be included.
Keep delivery permission current
Authorize export creation, job status and package retrieval for the specific tenant and resource. Recheck the recipient's current entitlement when delivering the result. Permission at job submission can become stale while a large export is being prepared. OWASP's authorization guidance calls for permission checks on every request, including access to individual resources.
Treat the asynchronous export as a durable job, with separate generation and delivery outcomes. If a recipient loses access before completion, the product needs an explicit path for an authorized workspace owner to resolve the handoff. Do not let a queued job silently preserve an obsolete permission decision.
A link with an expiry is still a delivery credential if possession grants access. Choose the delivery mechanism and revocation behavior according to the export's sensitivity. The acceptance brief should state when the file becomes unavailable and how a failed download can be retried by an authorized recipient. A successful HTTP response alone is not customer acceptance.
Close access through an explicit state transition
The proposed workflow below puts package verification before the agreed closure step. It is one product design, not a universal requirement to wait indefinitely for a customer acknowledgment. Define what happens when the recipient does not respond, when the export fails validation or when the closure request is withdrawn before execution.
Access closure has several consumers. End or restrict interactive sessions according to the chosen state, revoke affected credentials, stop newly admitted workspace work and resolve queued operations. Reconcile integration callbacks and generated-file access. Use the SaaS authorization matrix to test a closed workspace through each entry point, including direct API requests.
Do not equate access closure with deletion completion. Data classes may follow different already approved retention rules, and some asynchronous cleanup can fail. The product should expose the relevant status accurately and keep an operational record of completed actions and unresolved work. This design brief leaves retention durations and policy decisions to the responsible organization.
Write a receipt support can explain
The final receipt should connect the closure request to the export ID and agreed cutoff, identify the delivered scope and report the access state. If cleanup remains pending, name that state with a support path instead of presenting a completed deletion.
Keep sensitive internal evidence behind appropriate access controls.
Test the handoff with a fictional tenant before release: inspect a package, follow an attachment reference, report a deliberate omission, revoke a recipient during generation and retry a failed closure step. The package fixture covers only the first part. Product, security and operations owners must supply evidence for the remaining acceptance rows before the workflow can be called complete.
Sources
Documentation checked .
