Companion handout for the CISOSE 2026 tutorial Building and Verifying AI Systems with Agentic AI — Chia-Kai Chang, National Central University.
Promised on stage, posted after the session.
This is a redacted, reusable version of the consent and data-handling procedure used on a production education platform that also serves as a research instrument. It is written as a template with commentary: fill in the bracketed parts, and read the commentary for why each clause is worded that way.
Not legal advice. This reflects one team's practice under one institution's ethics framework. Your regulator, your institution, and your jurisdiction come first.
The tutorial's checklist puts governance at layer 5, and the reason is that most governance failures are not policy failures. The policy is fine. It is simply not connected to anything that runs.
So every clause below is paired with the question that turns it into a check:
Could I write a test that fails if this stopped being true?
If the answer is no, the clause is a promise. Promises degrade silently. Pipes do not.
This procedure covers: [systems / data types]
It does not cover: [explicitly out of scope]
Approving body: [ethics committee / IRB], approval reference [number]
Owner: [named person], reviewed [frequency]
Commentary. Name a person, not a team. An unowned procedure is discovered to be unowned at the worst possible moment.
Testable as: does the approval reference in the code match the one on the consent screen? This is a one-line assertion and it catches a real class of drift.
Participation in research is independent of [grades / service level / access].
A person who declines, or later withdraws, retains full access to [the service],
and [the assessment] is computed identically.
Commentary. This is the single most important clause when there is a power imbalance between the operator and the participant — teacher and student, employer and employee, clinician and patient. Consent obtained under an implied penalty is not consent.
State it in the consent text in plain language, and state it again wherever the person might suspect otherwise.
Testable as: a genuine test, and worth writing. Take a participant record, flip the consent flag off, recompute the assessment, and assert the result is byte-identical. If that test does not pass, the separation is decorative.
Consent is:
- explicit [affirmative action, not a pre-ticked box]
- versioned [consent record stores the exact document version agreed to]
- durable [re-shown when the document version changes]
- granular [separate items for: service use | research use | sensitive types]
- withdrawable [self-service, from the same place it was granted]
Record stores: person, document version, timestamp (UTC), scope granted, channel.
Commentary. Versioning is what most implementations miss. If you revise the consent document, everyone who agreed to the old one has consented to something that no longer exists. Storing a version means you can answer "what exactly did this person agree to, and when" — which is the question you will actually be asked.
Prefer in-platform consent to an external form. A form on a third-party service creates a second data controller, a second retention policy, and a record you cannot join to anything.
Testable as: publish a new document version in a staging environment and assert that existing users are re-prompted. Assert that a consent record can never be written without a version string.
The following require separate, explicit consent and are never bundled with §3 general
consent:
- [physiological / biometric data]
- [free-text reflections and open responses]
- [audio or video recordings]
- [any special-category data under your jurisdiction]
Commentary — two traps.
Trap one: inference creep. Collecting a physiological signal is not the same act as inferring a mental or emotional state from it. Several jurisdictions treat them as different legal categories, and in education and the workplace the second may be prohibited outright regardless of consent. Write down which one you are doing, in the spec, and use language that matches. "Heart-rate variability was recorded" and "stress was measured" are different claims, and only one of them may be yours to make.
Trap two: free text. Open responses are routinely classified as low-risk because they are "just text". They are the highest-risk field in most systems, because people put anything in them. Treat them as sensitive by default.
Testable as: assert that the sensitive-category flag cannot be satisfied by the general consent record. A schema-level constraint is better than a code path here.
All research data leaves the system through [one named route], which:
- applies de-identification on the way out, not afterwards
- records requester, scope, purpose, and timestamp
- refuses any request lacking a current approval reference
There is no second route. Direct database access for research purposes is not granted.
Commentary. Building an export path is also building the fastest way to lose everything at once, so it should be the narrowest and most boring part of the system. The temptation to make a single friendly exception for a trusted colleague is exactly the thing this clause exists to prevent — not because the colleague is untrustworthy, but because an exception is unlogged, and next year nobody can reconstruct what left.
De-identification on the way out matters. "The recipient will handle it carefully" is not a control.
Testable as: assert that the export function cannot be called without an approval reference. Then check the log: can you answer who asked, what they got, and when, for every export in the last year? If not, the route is not the only route.
On withdrawal:
- the link between person and research record is severed within [period]
- already-published aggregate analyses are not retracted [state this plainly]
- service access and [assessment] are unaffected (see §2)
- the person receives confirmation of what was done
Commentary. Be honest about what withdrawal can and cannot undo. Data already included in a published aggregate cannot be pulled back out, and saying so up front is better than an implied promise you will have to break. Severing the link is usually the right mechanism, and it is a different operation from physical deletion — say which one you do.
Testable as: the hard one, and the reason to write it as a test. Withdraw a test participant, then run every research query and assert that person is absent from all of them. Most systems have one query that was written before the withdrawal feature existed.
Raw [type]: retained [period], then [action]
Derived [type]: retained [period], then [action]
Audit logs: retained [period]
Deletion is: [automated job | manual, with named owner]
Commentary. An unautomated retention rule is a rule that will not happen. If deletion is manual, name the owner and the review date in this document, and accept that you have recorded a risk rather than a control.
Testable as: the strongest signal here is not a unit test but a query — is there anything in the store older than the stated retention period? Run it on a schedule and alert on non-zero. A retention policy with no such query is a document, not a pipe.
Data from [region] is stored in [region].
Front-end and identity are served from [location].
Region is fixed at [the moment consent is given] and recorded with the consent record.
Commentary. Distinguish storage localisation from data localisation before writing this clause; they are different commitments with very different cost, and teams routinely promise the second while implementing the first. Fix the region at consent time — a person who moves should not silently change the legal basis for data already collected.
Testable as: assert that every record carries a region flag and that no query joins across regions without an explicit, reviewed exception.
An incident is: [definition — include "data reached someone who should not have seen it"
even where no external party was involved]
Report to [role] within [period]. Record: what, when, who was affected, what changed.
Commentary. Define the term wide enough to include near-misses and internal wrong-context access. A definition that only triggers on external breach will classify your most instructive incidents as non-events, and you will learn nothing from them.
Testable as: this one is honest to mark as not testable. It is a process clause. Say so — a checklist that pretends every row is automatable is a checklist people stop trusting.
That backlog is the deliverable. A completed template with no backlog usually means the questions were not asked seriously.
Released with the tutorial materials. Reuse freely; attribution welcome. Adapt to your own institution's requirements — do not adopt as-is.