SaaS product engineering

SaaS data export and account closure: define the handoff

Make the customer outcome inspectable: agreed scope, readable data, authorized delivery and a clear closure state. This product brief connects those decisions to evidence and ownership.

Example package
Two fictional records, one attachment and a custom JSON manifest
Acceptance boundary
Package integrity, source completeness and customer handoff are separate checks
Status
Package fixture verified; operational acceptance brief remains unexecuted
A carefully packed blue data container with document cards and a small attachment object, being handed across a neutral tabletop beside an amber gate.
Conceptual illustration of a verifiable data handoff before an agreed access transition.

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:

Proposed ownership and evidence for an export and workspace-closure workflow
DecisionProposed ownerAcceptance evidence
Scope and cutoffProduct ownerIncluded objects, exclusions and treatment of later writes
Authority to close and receiveSecurity ownerAuthorized tenant decision maker and current recipient access
Package contractEngineering ownerVersion, identifiers, counts, checksums and resolved references
Customer verificationCustomer and supportReadable sample, accepted handoff or documented missing content
Access closureOperations ownerSessions, credentials, jobs and file access reach intended states
Retained dataData ownerExisting approved policy mapped to each data class
Failure handlingSupport ownerDefined 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 custom manifest lists records.csv and files/note.txt with hashes and sizes. Record r1 references the note attachment; record r2 has none. Source-snapshot reconciliation is a separate check.
Figure 1. Structure of the verified fictional package. Payload hashes do not prove that every in-scope source object was exported. View full-size figure.

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.

The proposed workflow agrees scope and cutoff, prepares and verifies a package, delivers to an authorized recipient, then closes access under the agreed condition. Retention execution has its own status.
Figure 2. Proposed customer handoff. Export failure, recipient changes and nonresponse require explicit exception paths before the closure condition is considered met. View full-size figure.

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 .

  1. RFC 8493: BagIt file packaging format
  2. OWASP: authorization guidance