Subprocessors
Every third party TDACorp Identity sends data to or stores data with in order to run, and every outside service the code can call. The register is read off the configuration and code that actually calls each one, not off a vendor contract list kept somewhere else.
On this page
Draft
Status
Last reviewed 5 October 2026. TDACorp Identity is pre-production. Each row below was re-checked against the code and deployment documents on that date. No outside party has audited this register.
How to read this register
Each outside service the platform can reach is placed in exactly one class.
| Class | Meaning | Listed in the register below |
|---|---|---|
| Subprocessor | A vendor that stores or handles personal data on the platform's behalf in order to run it | Yes |
| Optional subprocessor | A vendor that handles data only when the operator turns a setting on | Yes, marked optional |
| Written but not yet running | A vendor named in a workflow or checklist that has not yet been run | Yes, marked as such |
| User-initiated federation | A sign-in provider the person chooses to use, which receives their authentication request | Separate table |
| Sent no personal data | An outside call that carries no information identifying a person | Separate table |
| Not used | A service that is not called by anything deployed | Separate table |
Subprocessor register
| Name | Purpose | Data sent or stored | Location as documented | Since | Link |
|---|---|---|---|---|---|
| Vercel | Hosting and application infrastructure. Runs the Next.js web app and the identityd function, the scheduled job, and DNS for tdacorp.in | Every request to the platform passes through it. Runtime logs hold one JSON line per request. Environment secrets are held as sensitive variables | The platform's configuration sets no function region, so the host's default applies. The Vercel project settings report the function region as iad1 (US East, N. Virginia), with no failover, read on 2026-10-10 | Not documented | vercel.com |
| Neon | Primary database (Postgres 18) | Every persistent record the platform keeps: accounts, credentials (as hashes or sealed), sessions, profile pictures, the audit log, queued emails (sealed), and personal-data exports while they exist | Neon has no Indian region. The project is in AWS US East 1 (N. Virginia), read from the Neon console project list on 2026-10-10. The owner waived India placement for pre-production on 2026-09-30 | Waiver dated 2026-09-30. Provisioning date not documented | neon.com |
| Resend | Transactional and security email, through its REST API at api.resend.com | The recipient address and the text of each message: verification and sign-in links and codes, recovery messages, and the security alerts described on the security practices page. The send is made from the address in the [email].from setting of the configuration the deployment runs | Not declared by this platform's configuration | Not documented | resend.com |
| Grafana Cloud (optional) | Receives metrics, traces and the request log over OTLP/HTTP, only when OTEL_EXPORTER_OTLP_ENDPOINT is set | Request log lines: route pattern, method, status, duration, tenant id, client id, an HMAC of the caller address, error class, outcome, request id, trace id and deploy id. Never raw addresses, emails, tokens or secrets. Every attribute passes an allow-list | The documented example endpoint host contains ap-south-1. That is a hostname, not a statement of where data is processed | The deployment plan states no collector is configured. Nothing has been shipped to a real collector | grafana.com |
Written but not yet running
These are named in repository workflows and the owner's setup checklist. The deployment documents state they are written and have not yet been run. They are listed so the register is complete the day they start.
| Name | Purpose | Data sent or stored | Location as documented | Link |
|---|---|---|---|---|
| GitHub (Actions and repository hosting) | Runs continuous integration, the migrate-then-deploy pipeline and the nightly backup and monthly restore-drill workflows | The deploy pipeline holds the owner database URL as an Actions secret. The backup workflow reads the whole database to dump it, so personal data passes through the runner while the dump is made and before it is encrypted | Not declared | github.com |
| Cloudflare R2 | Private object storage for age-encrypted nightly dumps | An encrypted database dump. The dump holds sealed keys and data-key-wrapped data, never the key-encryption key. The private decryption key is kept offline | Not declared. The platform specification calls for backups in a second Indian region. No region is recorded for the bucket | cloudflare.com |
| A healthcheck service and an external pinger | Dead-man's-switch pings and an optional external trigger for the scheduler. The owner chooses the services. The documentation names cron-job.org or a scheduled GitHub Action as examples | A ping to a secret URL, or a request bearing a bearer secret. No personal data is in either | Not declared | Not configured in this repository |
User-initiated federation
| Name | Purpose | Data sent | Data received | Status |
|---|---|---|---|---|
| Google (OpenID Connect) | Sign in or link an account with Google, if the person chooses it | The person's browser is redirected to Google with a state value, nonce and PKCE challenge. The server exchanges the code with Google | Subject identifier, verified email, display name and other profile claims from Google. When an account is created through the provider, the server also fetches the picture from the URL the provider gives and stores it as the profile picture | Built, with the code paths for login, linking and step-up. The trust pages state that sign-in with Google or GitHub is not offered today. An operator must register a provider before it is active |
| GitHub (OAuth) | Sign in or link an account with GitHub, if the person chooses it | As above, with GitHub's authorize and token endpoints | User and email lists from the GitHub API | Same as above |
When a person chooses one of these, that provider is acting on the person's own instruction and under its own terms. It becomes a subprocessor-like recipient of the authentication request only for the person who made that choice. This register will be updated the day a provider is registered for production.
Outside calls that send no personal data
| Name | Purpose | What leaves the system | Why it is not personal data |
|---|---|---|---|
Have I Been Pwned range API (api.pwnedpasswords.com) | Check a password against a breach corpus when it is registered, set, changed or recovered, and in the background after each successful password sign-in | The first five hexadecimal characters of a SHA-1 hash of the password, with a padded response request | Never the password, never the full hash, nothing that identifies the account. The prefix is never logged. |
| Registered clients' endpoints (webhooks, back-channel logout, Shared Signals receivers) | Deliver events to a product the account holder signed in to | Event payloads to a URL the product registered. Payloads follow the audit rule of identifiers and hashes, never raw emails | These go to the product's own receivers, not to a TDACorp vendor. The product is responsible for them |
| Metadata and key documents of a configured federation issuer | Fetch discovery and keys for Google or GitHub | A plain HTTPS fetch of public documents | No person data is sent |
Not used
This table lists services the code does not call. It is verified against source rather than assumed.
| Service | Status | Evidence |
|---|---|---|
| Analytics or advertising tools | Not used | No analytics or third-party script is loaded. The pages are served with a content security policy that allows only this site's own scripts and styles |
| A cloud key-management service | Not used | Pre-production key management is a software provider. The cloud KMS arm is not implemented |
| Vercel Blob, UploadThing or any storage vendor | Not used | Profile pictures and exports are database rows |
| Redis or another cache vendor | Not used | No separate cache service is called |
| Any AWS service | Not used | No AWS service is called by anything deployed |
| Third-party fonts or images | Not used | The pages load no third-party scripts, fonts or images |
| Error-tracking vendor | Not used | The client-error intake, when enabled, stores into the platform database |
Data flow by feature
| Feature | Vercel | Neon | Resend | Grafana Cloud (optional) | Anyone else |
|---|---|---|---|---|---|
| Sign-in with password | Request handled | Credential hash read, session written, audit event | Sign-in alert email if the browser is new | Request log line | Have I Been Pwned: a padded 5-character prefix request when a password is set, and again in the background after each successful sign-in |
| Sign-in with passkey | Request handled | Public key read, challenge stored, session written | Alert if new browser | Request log line | None |
| Magic link or email code | Request handled | Link or code stored hashed | The message with the link or code | Request log line | None |
| Registration | Request handled | Account and unverified email created | Verification email | Request log line | Have I Been Pwned when a password is set |
| Account recovery | Request handled | Recovery request stored | Recovery, hold and cancel emails | Request log line | Have I Been Pwned when a new password is set |
| Federated sign-in (if registered) | Request handled | State and identity link | None unless an alert is due | Request log line | Google or GitHub, chosen by the person |
| Session and device pages | Request handled | Sessions and devices read or revoked | Alert emails on device trust changes | Request log line | None |
| Personal-data export | Request handled, file served as a download | Export built, signed and stored for 7 days | The export-ready email, and the alert for the export request | Request log line | None |
| Account deletion and erasure | Request handled, then scheduled job | Deactivate, then erase after 30 days | Deactivation notice | Request log line | None |
| Connected apps and OAuth tokens | Request handled | Consent, token families | A notice email to the account owner when a refresh token is reused, and when a back-channel logout or webhook is disabled | Request log line | The product's own endpoints for logout and webhooks |
| Admin console | Separate hosted app | Reads and writes via identityd | Role-change and access notices | Request log line | None |
| Operations alerts | Scheduled job | Reads recent audit rows and worker state | Alert email to the operator address | Alert counter | Healthcheck service, if configured |
| Backups (written, not run) | None | Read by the dump login | None | None | GitHub Actions runner, then Cloudflare R2 |
What is not shared
| Data | Not shared with any vendor |
|---|---|
| Passwords | Only a salted Argon2id hash is stored. The password itself reaches only the platform. Only a 5-character prefix of its SHA-1 digest goes to the breach corpus |
| Authenticator secrets, recovery codes, signing keys | Sealed or hashed in the database. Not sent to any vendor in readable form |
| Session secrets and tokens | Stored as digests. Not placed in logs or telemetry |
| Raw network addresses in telemetry | The request log carries an HMAC of the address, never the address itself |
| Email addresses in telemetry | Not emitted. The telemetry allow-list has no free-text field |
| Advertising or analytics identifiers | None exist |
| Biometric data | A passkey's biometric check happens on the person's device |
| Data sold to or shared with data brokers | None. There is no such feature |
Change notification
| Question | Answer as documented |
|---|---|
| How is this list kept current? | It is read off the configuration and code and re-checked when the trust copy is reviewed. The date at the top is the last review date |
| What triggers an update? | Adding or removing a vendor. The page states that it will change when any listed-as-absent service is added |
| Is advance notice promised? | No. The repository defines no notice period and no mailing list for subprocessor changes |
| Where is the change visible? | On this page, with a new review date |
| Is there a history of changes? | The page's own history is held in the repository's version control. No separate changelog is published |
Note
Pending decision by the owner: whether to commit to advance notice, and to which channel, before a subprocessor is added.
How to object
There is no formal objection procedure. If you object to a subprocessor on this list, email security@tdacorp.in with the vendor and your reason. We will read it and reply, but no response time is promised, and the repository defines no process under which a customer can require a vendor change. For a product built on this platform, the arrangement is a conversation with TDACorp. See the data processing addendum.
What this page does not claim
| Not claimed | Detail |
|---|---|
| A certified or audited register | No outside party has audited it |
| A region for every vendor | Vercel and Neon are named in the register above. The primary database is not in India during pre-production, by owner waiver. No region is declared for the other vendors |
| That optional or not-yet-run vendors are live | Grafana Cloud, the backup workflows, Cloudflare R2 and the healthcheck service are marked as optional or not yet run. The deployment plan states no collector is configured |
| That the federation providers are offered today | The code exists. The trust pages state that sign-in with Google or GitHub is not offered |
| Coverage of other TDACorp products | This list is scoped to the identity platform itself. Other products have their own subprocessors |
| Staff and mailbox systems | The register covers systems that process account data. The systems behind the operator mailboxes that receive security@tdacorp.in mail are not documented in this repository |
| A notice period or an objection right | Neither is defined |
| Dates a vendor was engaged | Not documented, so none is given |