Legal Pages (Imprint & Privacy)
Hephaestus ships with two legal pages: /imprint and /privacy.
The webapp renders them from Markdown files that nginx serves directly.
This page explains how the webapp resolves them and each self-hosted operator's responsibilities.
The built-in “not configured” pages are placeholders, not legal notices.
Each operator must supply their own notices.
On the Helm chart, put them in a ConfigMap and name it in webapp.legalOverrides, as Deployment-specific overrides describes.
First-login consent notice
The first-login screen carries no operator-specific text.
It states the terms of use and links to /privacy and /imprint.
Those pages identify the deployment operator, the data it stores, and its retention periods.
Thus, the same text is accurate on every instance.
These overrides make it complete.
The sign-in and first-login screens have their own /privacy and /imprint links.
They render without the site footer.
On a deployment that still serves the placeholder, the first-login screen links to no legal notice.
- Configure both pages before the first user signs in.
When the account holder selects Save and continue, the ledger records two facts against the notice version shown:
- The account accepted the terms with I accept the terms of use.
- The screen presented this text, which links to the privacy notice.
Both facts come from one checkbox. The ledger records the text presented to the account and its agreement. It does not establish that anybody opened the link.
Where the screen asks the research question below, it records the research answer as a third, separate decision. Either answer completes setup. Hephaestus records nothing until the account holder selects Save and continue. Your data in Hephaestus describes the same screen for the person who answers it.
The optional research question
HEPHAESTUS_RESEARCH_ORGANIZATION names the organization that runs research on this deployment.
Its presence determines whether the research question appears.
Integration settings lists the setting with the other deployment settings.
The organization does not need to be academic.
Choose a name that reads correctly in the sentence "If you say yes, the organization may use your data for research."
Consent must be informed. This includes the controller's identity (EDPB 05/2020 § 3.3). Thus, the configured name appears beside the choice on the first-login screen and in account settings, not only in a link.
HEPHAESTUS_RESEARCH_ORGANIZATION="Technical University of Munich (AET)"
By default, the variable is unset.
In this state, no research question appears.
First-login setup contains only the terms.
The account-settings switch is hidden.
PUT /user/consent/research returns 404.
What the question asks
The screen asks Allow research use of your data? with two answers: Yes, allow research use and No, keep my data out of research. The legal basis is consent under Art. 6(1)(a) GDPR. It is a broad consent to an area of research, not to one research project.
Recital 33 GDPR allows this when the purpose of the research cannot be fully specified at collection. EDPB 05/2020 paragraphs 153 to 163 set the conditions. The obligations below follow from those conditions.
The area of research is how developers work and learn, and how AI systems can review and support that work. It includes building and running benchmarks and evaluation datasets for such AI systems. The data it may use is:
- The participant's work in the tools that the project connects.
- Hephaestus results and problems and feedback about that work.
- The participant's responses to that feedback.
- How the participant uses Hephaestus, including conversations with Hephaestus and answers to research surveys.
Sign-in credentials and access tokens are never used. Slack messages that a participant stops Hephaestus from using stay out of research too.
The consent is optional and separate from the terms. Saying no or withdrawing has no disadvantage (Art. 7(4) GDPR).
Research that falls outside this area is not covered by this consent.
For such research, change the wording with a new WORDING_VERSION after legal review.
A change is a new question
A change to the organization name is a new question. Hephaestus treats it as one.
Every research decision records the organization that the question named in consent_decision.research_organization.
Consent to research is consent to the organization that runs it.
After a rename, no other record identifies the organization that the account saw in the question.
If the setting has a different name, no account's grant to the previous one authorizes anything.
participatesInResearch reports false.
Setup asks the research question again.
Earlier decisions stay in the ledger as a record of the questions and answers at that time.
Terms acceptance stays unchanged because the terms did not change.
A change to the wording is a new question for every account.
A new WORDING_VERSION is a new notice version.
Every account sees the setup screen once more, with the terms and, where an organization is named, the research question.
An earlier yes is not carried over to a broader scope.
Only a decision on the current version and the current organization authorizes anything.
Until an account answers, participatesInResearch reports false and research survey invitations stop.
Even a cosmetic rename gives every account one more setup screen. Make a change to the name or the wording deliberately.
Both the setup screen and the settings switch return the organization that they displayed.
If a submission names an organization that this instance no longer runs, Hephaestus refuses it with 409.
A tab left open across a change cannot record a decision about an organization that its reader never saw.
Research-purpose surveys and their email invitations require a current grant for the configured organization. Withdrawal stops new research survey participation and invitation delivery. It does not stop ordinary practice reviews or erase rows in the instance database. The research team removes the data from its datasets that are not yet anonymized. The Slack App Home links to account settings rather than maintaining a separate research decision.
Withdrawal
A participant withdraws with one switch, Allow research use of my data, in User settings → Research participation. This is as easy as giving consent (Art. 7(3) GDPR). New research use stops, and research survey invitations stop. The research organization removes the participant's data from datasets that are not yet anonymized. Research done before the withdrawal stays lawful.
Anonymized data in a published result or dataset cannot be traced back and cannot be removed.
Withdrawal does not erase other stored data by itself. Account erasure is a separate request.
Release a structured research dataset
A research disclosure is a JSON file for the configured research organization. It contains structured practice history for people whose current research grant permits it. It is pseudonymous personal data, not anonymous data. Keep it within the authorized research team.
The file excludes participant and model text, source code, credentials, and provider identities. It retains historical records with their recorded limits. A legacy record does not prove a capture contract.
Every operation below requires the instance-admin role and the administrator's own session. By default, every operation also requires the administrator's own fresh passkey verification. This requirement applies even when the instance does not require passkeys for ordinary admin access. An isolated test instance can turn off this additional confirmation. See Test instances without additional confirmation.
A user view or installed-client session cannot perform these operations. Browser requests also need normal CSRF protection.
- When the instance requires the additional confirmation, verify your passkey through User settings → Passkeys.
- Submit
POST /admin/research-disclosureswith the workspace ID as a string,firstDay,lastDay, anduseUntil. The window uses UTC days and includes the last day. Choose a window of 1 to 400 days that ends no later than today. SetuseUntilto the future date and time that the study protocol permits. The request cannot change the research purpose, organization, or notice version. - Save the returned attachment and its dataset ID from the filename. Hephaestus records the disclosure and its protected participant mapping, but stores no copy of the file. There is no redownload operation. A new request creates a new disclosure, including after an interrupted download.
Before further analysis, check whether a participant's removal is owed:
- When the instance requires the additional confirmation, verify your passkey again if it is no longer recent.
Then submit
POST /admin/research-disclosures/removal-checks. This operation records newly detected obligations. It returns open disclosures with a removal owed or an expired use-until date. An empty list does not mean no datasets were released. - Remove each listed participant key's rows from every retained copy that is not yet anonymized. Remove dependent rows and every whole-review fact that names the key too. If this is not possible, delete the copy.
- After removal, submit
POST /admin/research-disclosures/{datasetId}/removal-receiptswithparticipantKeys. This records your statement that the removals were completed. A later research grant does not cancel a removal owed under the earlier grant.
Stop using the file at its use-until date.
After every retained copy is destroyed or anonymized, submit POST /admin/research-disclosures/{datasetId}/closure.
Set closure to DESTROYED or ANONYMIZED, according to what was done.
Closure removes the protected participant mapping and keeps the disclosure receipt.
Hephaestus cannot reach or revoke a downloaded copy. A removal receipt or closure is an operator's statement, not a check of the research team's storage.
No separate consent for datasets
The consent has no second choice for sharing or publishing datasets. Only anonymized data leaves the research team. Anonymous data is outside the GDPR (Recital 26). Paragraph 47 of EDPB Guidelines 1/2026 (draft, adopted 15 April 2026) lets a broad consent cover the provision of data within the research area.
A release needs a separate choice and a new wording version when it would do any of the following:
- Contain data that is not anonymized.
- Serve a purpose outside the stated area of research.
- Go to a third country without adequate safeguards.
What operators must do
The broad consent is valid only if the operator meets these obligations.
Meet all of them before you set HEPHAESTUS_RESEARCH_ORGANIZATION, and keep to them while the research runs.
- Before any research export, analysis, or benchmark run, apply the latest
RESEARCH_PARTICIPATIONdecision of each account. Use only a grant for the current notice version and the current organization. - Remove the data of withdrawn accounts from datasets that are not yet anonymized without undue delay. Treat an erasure request for data in such a dataset the same way. Treat a Slack message-use opt-out the same way for the affected messages.
- Keep participants regularly informed about the research. Give the current research purpose, working methods, projects and released datasets. Give a way to receive updates as the research progresses. Use a research information page or a named research contact who answers questions and sends these updates. An email address that only waits for questions does not meet this duty. See EDPB 05/2020 paragraphs 161 and 162 and footnote 74. See also EDPB 1/2026 (draft) paragraphs 48 and 49.
- Assess whether the research needs an ethics committee vote. Get the approval where your institution or the research process requires it. Do not state an approval in the notice that you do not hold. A vote is not required for every study (TUM ethics committee).
- Keep the research team separate from grading and line management. A power imbalance can weaken the free choice of a participant. See EDPB 05/2020 paragraphs 16 to 24 and 46 to 48. See also Recital 43. Instance admins can read research survey answers, so give the admin role only to people who meet this rule.
- Test a dataset for re-identification before you call it anonymous. Release it only if the test passes. Free text and code are hard to anonymize (EDPB 1/2026 paragraph 164).
- Honor the AI choice of each participant in benchmark runs. Model providers may see only pseudonymized data, under a data processing agreement.
- Do not use the consent for browsing activity from the browser extension. The privacy notice already says so.
- Keep each safeguard that the consent text states. The research team replaces identifiers with a code, stores the key apart, and screens text for names. It restricts access to the team and its processors. It sends model providers only pseudonymized data, under a data processing agreement.
Publish the retention and recipient details of the research in your privacy notice.
ConsentService.WORDING_VERSION identifies the text that an account accepted.
That text is the first-login screen, published in a signed release and immutable in git.
The webapp holds the same constant beside the text.
It submits its own constant.
Thus, a browser tab that predates a deployment cannot record acceptance of text it never rendered.
A fork that changes the text must change both constants in the same commit. Such a change gives every account one more setup screen. Make it on purpose.
Operator obligations
Under Art. 4(7) GDPR, the controller determines the purposes and means of processing. Use of Hephaestus does not make the upstream project your controller. § 5 DDG applies to qualifying German digital services. Links to the upstream notices do not describe a separately operated deployment.
- Identify the organization responsible for your deployment and its processing purposes.
- Publish a privacy notice with the information that Arts. 13 and 14 GDPR require. It must include data about contributors who never sign in.
- Publish the operator identification that your jurisdiction requires.
Resolution
At page load, the webapp fetches the relevant Markdown file in this priority order. It uses the first file it finds:
| Priority | Path | Typical source |
|---|---|---|
| 1. | /legal-overrides/<page>.md | Mounted by the operator |
| 2. | /legal/_disclaimer/<page>.md | Shipped safety-fallback |
<page> is imprint or privacy.
A banner alerts end users whenever the webapp serves the disclaimer.
Publish your pages
Deployment-specific overrides
Every public deployment uses this configuration.
You write two Markdown files, imprint.md and privacy.md, and the webapp serves them instead of the safety-fallback.
-
Put both files in a ConfigMap in the release namespace:
kubectl --namespace hephaestus create configmap hephaestus-legal-overrides \--from-file=imprint.md --from-file=privacy.md -
Name the ConfigMap in your values file:
webapp:legalOverrides: hephaestus-legal-overridesThe chart mounts it read-only at
/usr/share/nginx/html/legal-overrides. The webapp Pod waits until the ConfigMap that it names exists.
A container that runs outside the chart reads the same two files from a read-only mount at /usr/share/nginx/html/legal-overrides.
The webapp runs as UID 101, so that user must be able to read the files.
The webapp reads the files on each request. Kubernetes updates a mounted ConfigMap within about a minute, so a change needs no redeploy.
Resolution is per page: a single-file override leaves the other page on the built-in fallback. Verify both pages identify the correct operator.
Built-in fallback (developer default, not a production configuration)
If no overrides are mounted, the webapp serves a clear placeholder (_disclaimer/*.md).
It tells visitors that no legal content is configured.
It asks them to contact the operator directly.
The UI shows a red banner.
This is not a valid imprint or privacy notice. You must not use it in production. It is for local development and visible identification of misconfigured deployments.
Authoring guidelines for a custom privacy notice
Use Art. 13 GDPR as the outline. Hephaestus processes personal data in at least the following categories, which your privacy notice must cover:
- Identity and authentication — Hephaestus-native auth federates to GitHub or GitLab. Each federated identity stores the provider, stable subject id, login, email-at-signup, and display name (ADR 0017).
- Repository synchronization — each configured repository supplies pull/merge requests, issues, reviews, review comments, commit metadata, and author profile information. The notice must state the retention triggers that Data retention lists. The mirror is erased when the last workspace stops monitoring the source repository. Disconnection of the workspace's integration or a workspace purge also erases it.
- Account settings and email notifications — user preferences and the provider-verified primary email address for account-security and deletion email. With a configured relay, this also includes optional notification subscriptions, survey invitation records, and unsubscribe capabilities. The notice must name the relay operator as a recipient.
- AI-assisted features — if enabled: messages sent to the configured LLM provider, persisted conversations, generated practice results.
- Server logs — IP address and request metadata.
- Log collection — you can ship container logs to a log store such as Loki (Collecting logs). Name the store's operator and retention in the notice. Hephaestus ships no error telemetry service.
- Public activity page — if you allow it, use the template below.
- Workspace addresses — if you turn them on, use the template below.
Determine a lawful basis for each processing purpose with your data-protection adviser. Neither self-hosting nor acceptance of terms supplies one automatically. Art. 6(1)(f) GDPR does not apply to public authorities processing data in the performance of their tasks.
For international transfers, document the applicable Chapter V safeguard for the actual recipient, service and destination. Verify current adequacy decisions, certification scope where relevant, and contractual safeguards rather than inferring coverage from a provider's brand.
The public activity page
Allow public activity pages is off by default. When it is on, a workspace admin can publish the activity of the workspace's public repositories to anyone. The page lists members and outside contributors who never signed in. Each person can hide.
Before you turn on the setting:
- Determine a lawful basis for the publication with your data-protection adviser.
- If you are a public body, record the task for which the publication is necessary.
- In the German private sector, check entries 7 and 8 of the DSK list.
- If the people on the page are employees, check employment law. In Germany, a works council co-determines it (§ 87(1) no. 6 BetrVG).
- Add the text below to your privacy notice.
- Tell workspace admins to keep course workspaces private, and to tell the members before they publish a page.
- Give your privacy contact a way to hide a person who has no account.
### Public activity page
If a workspace administrator publishes a public activity page, anyone can read it without sign-in.
For each person who contributed to the workspace's public repositories, it shows the display name,
login and avatar; the pull requests opened, merged and reviewed, the issues opened and the active weeks
in a selected period; a Contributions total, a position number and links to the work. The data comes
from the public repositories on [GitHub or GitLab]. The page never shows practices, practice results,
feedback, Slack or Outline content, or AI review content.
Purpose: [purpose]. Legal basis: [legal basis]. The page is computed on each request and holds no
copy. Responses can be cached for up to 60 seconds.
**Right to object.** You can object at any time to your appearance on public activity pages. Turn off
**Show me on public activity pages** in User settings, or select **Hide me** when a workspace with a
public activity page asks. Without an account, contact [privacy contact]. We stop at once, and you
also leave every total on the page.
Workspace addresses
With workspace addresses on, each workspace has its own host, such as team.example.org.
Sign-in and its cookies stay on the instance host.
The web app asks for no cookie choice, because it sets no optional cookie.
The theme is one cookie, hephaestus-theme, on the workspace base domain (Domain=, SameSite=Lax, and Secure on HTTPS).
Thus, all workspace hosts share the light or dark mode.
It is a strictly necessary preference cookie that the reader sets, and it expires after one year.
A wildcard certificate through the DNS-01 challenge needs no proxy, and the DNS provider receives no request data. If a proxy or CDN serves the hosts, it is a recipient. Name it in the notice.
A workspace can have its own address, such as [team.example.org]. Sign-in and its cookies stay on
[example.org]. All these addresses share one strictly necessary cookie, hephaestus-theme, that
remembers your light or dark mode for one year. [If a proxy or CDN serves these addresses: its
provider, role and transfer basis.]
Verifying the configuration
A 200 status is not sufficient.
SPA-catchall proxies frequently return 200 text/html for missing files.
-
After deployment, confirm that the correct layer serves each page.
-
Check both the status and the content type:
curl -sI https://<your-host>/legal-overrides/privacy.md \| grep -E '^(HTTP|Content-Type)' # expect 200 + text/markdown if overrides are mountedcurl -sI https://<your-host>/legal/_disclaimer/privacy.md \| grep -E '^(HTTP|Content-Type)' # always 200 + text/markdown -
Fetch the body of the layer that you expect to serve the page: Confirm that it is your content.
curl -s https://<your-host>/imprint | head -c 200 # SPA shellcurl -s https://<your-host>/legal-overrides/privacy.md | head -n 3 # should start with your heading -
Open
/imprintin a browser. -
Open
/privacyin a browser.
If the red "not configured" banner appears, the webapp serves the disclaimer. You must still configure the legal pages.
Changing the texts over time
Markdown files are static resources.
Overrides under /legal-overrides/ use Cache-Control: no-cache, must-revalidate.
An edit on the host takes effect on the next page load.
Browsers revalidate every time.
The bundled fallback under /legal/ uses max-age=300.
Email activation
Configuration and a successful test email are technical checks, not institutional approval. Your privacy notice must name the mail relay that you configure as a recipient.
- Keep email disabled until the deployment record confirms the actual service, institutional arrangement, and relay retention terms.
- If you use a different relay, update the public notice's recipient and transfer information before you enable it.