Last updated August 26, 2026
Privacy Notice
Roman Dubovskoi, a self-employed professional established in Madrid, Spain, is the controller of the personal data described in this notice.
RunYour.App does not load Google Tag Manager or Google Analytics until you allow optional analytics. Advertising measurement is a separate optional choice covering Google Ads click measurement and Microsoft Advertising offline attribution. No Microsoft tag, pixel, or advertising script loads. Advertising personalization stays disabled. You can change either choice at any time through Cookie settings in the public footer or signed-in app header. The embedded YouTube demo is not loaded until you choose to play it.
Information processed
- GitHub account identity, email address, OAuth grant, and the repositories and revisions you select.
- Selected repository content and derived inventory, application specification, build plan, artifacts, and operational status.
- A write-only GHCR personal access token, its safe fingerprint, scopes, owner, and expiry.
- Project settings and write-only runtime environment values.
- Essential security and operational records needed to provide, protect, and troubleshoot the service, including IP address, session, request, error, and audit information.
- If you arrive from a Microsoft ad and separately allow advertising measurement, one validated Microsoft click ID held briefly in a lexical variable of an isolated first-party page and then in a dedicated protected attribution record. The normal page does not receive the identifier.
- Messages and identifiers you provide when requesting support, reporting abuse, or exercising a legal right.
Purposes and legal bases
- To authenticate you and provide the requested analysis, build, registry, deployment, and support functions. The basis is performance of the Terms where you contract personally and our legitimate interest in providing the service to your business otherwise.
- To secure the platform, prevent fraud and abuse, troubleshoot failures, enforce the Terms, and establish or defend legal claims. The basis is our legitimate interest in operating a safe and accountable service.
- To comply with binding legal requests and other applicable obligations. The basis is compliance with a legal obligation.
- To measure optional public-page use and the free-product funnel and, only if you separately allow advertising measurement, attribute acquisition from a Google Ads click in GA4 or a Microsoft ad click through a first-party offline conversion. Google and Microsoft conversion delivery each remain subject to their separate release gates. The basis is your consent, which you may withdraw at any time without affecting processing that was lawful before withdrawal.
- To deliver the embedded product demo after you choose to play it. The basis is our legitimate interest in explaining the service through a user-requested demonstration.
Cookies and analytics
Essential session and CSRF cookies are used for authentication and request security. Disabling them prevents authenticated product features from working.
If you allow analytics, Google Tag Manager loads Google Analytics only on an allowlist of published public pages of the production runyour.app hostname. It is not loaded on direct visits to project, settings, account or OAuth callback, API, or unknown paths. Current links from public pages into the product use a full page navigation, so a public-page tag is not carried into the destination document. It measures explicit public-page views, deployment call-to-action clicks, demo-video plays, and consented free-product funnel events. Automatic enhanced measurement is disabled. This can process technical information such as IP address, user agent, normalized public page path, referrer origin, strictly allowlisted campaign parameters, event timing, Google Analytics client and session identifiers, and a stable random pseudonymous analytics UUID generated by RunYour.App and sent to Google Analytics as user_id. That UUID is not derived from your email, GitHub identity, repository, or project identifiers. Raw query strings, repository names, branch names, commit hashes, project and pipeline identifiers, deployment URLs, email addresses, and GitHub usernames are not analytics event parameters. Ordinary deployment-button clicks with available Google Analytics identifiers are first sent to RunYour.App as one consented, pseudonymous event with a random event ID and only an allowlisted button ID and content group, then delivered to Google Analytics by the server. Modified and non-primary clicks may be sent directly from the public page without delaying navigation. The relayed click contains no RunYour.App user or account identifier. The stable pseudonymous user_id applies only to authenticated funnel events after a consented analytics context has been linked to the signed-in account. To limit relay abuse without storing an IP address or raw session key for that purpose, RunYour.App stores a one-way HMAC of the essential browser-session key in an append-only link to the active consent decision and separately with a relayed browser event. A decision can have no more than 20 distinct session links in its rolling 30-minute authorization window; those links cascade when the expired decision is purged. The HMAC is also used to enforce a maximum of 20 accepted browser events in that window and to find, fence, and suppress linked decisions and queued events after consent revocation or Google Analytics client-ID supersession. Neither the raw session key nor its HMAC is sent to Google Analytics.
If you separately allow Google Ads click measurement, the sanitized initial Google Analytics page location can include exactly one bounded gclid, gbraid, or wbraid. The raw click identifier is not sent to a RunYour.App analytics API, put in OAuth state, used as a custom event parameter, or stored in the internal product-analytics database. The original landing request necessarily reaches the frontend and gateway before browser code can remove its query, however, and may therefore appear in bounded infrastructure or security access logs under the operational-retention terms below. Browser code removes click identifiers from the address bar after the consent-safe page-view decision. If activated after the required backfill and canary, planned Google Ads conversion reporting will use an import from linked GA4. No Google Ads conversion import or readback is currently verified, and the current tag container has no direct Google Ads or Conversion Linker tag. Advertising personalization remains denied.
A Microsoft Advertising landing URL can contain one parameter named msclkid. On the exact eligible document request, first-party middleware returns a no-store page containing one synchronous first-party scrub script and no Next.js or Flight code. It removes every decoded spelling from the visible URL. Capture requires one exact lower-case parameter with one 32-character hexadecimal value, only on the reviewed /frameworks/fastapi landing. It preserves the page, approved campaign parameters, and any fragment that does not contain a copy of the click ID; copied values are removed as a whole.
On that one landing, the no-store shell clears window.name, removes the parameter from the visible URL, and keeps the valid value only in a lexical variable. It contains no Next.js, Google Tag Manager, Microsoft tag, worker, or third-party resource. Missing Fetch Metadata, direct aliases, malformed values, and values on other frontend-routed public landings receive a script-free no-store document that navigates to the server-constructed clean URL. Non-document requests are internally rewritten clean, and values found only after hydration are scrubbed without capture. Backend-routed account and API URLs are outside this landing mechanism; RunYour.App attribution code never adds a click ID to them.
A current combined cookie records your intent but does not by itself prove active server consent. The shell first obtains the current same-origin CSRF token and consent generation, then establishes the exact combined server context without the click ID. Only a successful response permits one same-origin capture request containing the click ID. If no current combined choice exists, the shell displays an explicit Accept or Reject choice. Reject erases the click first, records or preserves the exact non-advertising choice, attempts protected server revocation, and navigates clean. Accept follows the same context-first sequence before capture.
Privacy navigation, request failure, timeout, abort, beforeunload, pagehide, disabled JavaScript, and the absolute one-minute deadline all discard the optional click and navigate clean. The isolated initial shell's immutable Navigation Timing entry necessarily names the inbound URL, just as the original HTTP request necessarily reaches the service. No optional or third-party code runs in that document. After the true navigation, the normal page's Navigation and Resource Timing are clean, and the raw ID is not in window.name, rendered HTML, retained history state, a browser cookie, local or session storage, Google Analytics parameters, OAuth state, general product application or project records, client logs, or displayed errors. No UET tag, Microsoft pixel, Microsoft browser script, or Microsoft CSP host is used.
The dedicated Microsoft attribution record is encrypted and access-limited. The raw click ID is retained for at most 30 days to match the reviewed offline-conversion window and is deleted earlier when you explicitly withdraw or revoke consent, the Microsoft attribution consent decision expires, or an Apply upload is acknowledged without a per-item error. Decision expiry also suppresses nonterminal conversions. The separate 30-minute analytics-context authorization expiry does not by itself mean that an already bound Microsoft click ID has been physically deleted. That transport-level acknowledgment is not proof of attribution or Microsoft reporting. After that acknowledgment, only a keyed digest, status, and non-sensitive timing evidence remain to prevent duplicate delivery. A denied, revoked, expired, malformed, duplicate, replayed, or cross-account value cannot authorize an upload. The production gateway and application logging boundary must pass a live synthetic redaction canary before Microsoft attribution is enabled because the initial navigation reaches the service before middleware or browser code can clean the internal or visible URL. A failed or unavailable canary keeps attribution disabled.
For the 30-minute authorization horizon, the essential server session stores the active consent context, including the raw consented Google Analytics client and optional session identifiers, plus an opaque consent generation. A separate context-mutation guard in that session stores only a one-way server-keyed HMAC of the current client ID and no more than 20 recent client-ID rotation timestamps from the prior 30 minutes. The guard coalesces same-client updates and limits client-ID changes; it does not contain the raw client ID. This session state and guard are not sent as extra Google Analytics event fields, although the consented client and session identifiers are used to deliver analytics events. The anonymous session cookie is session-only; its server record expires on the same default horizon and is then removed by bounded periodic cleanup. For server-delivered authenticated events, the current advertising-user-data consent status is captured with the event; the same stable pseudonymous analytics UUID remains theuser_id, and advertising personalization stays denied.
Thirty minutes is the analytics authorization lifetime, not an exact physical-erasure promise for serialized server-session bytes. In an authenticated session, an expired raw Google Analytics client/session context can remain until consent revocation, context overwrite, logout, the next locked bootstrap or analytics mutation, a later session save that lazily scrubs it, or session expiry. It cannot authorize capture or delivery after its 30-minute expiry. Production authenticated sessions use sliding expiry, but a save that extends the session first lazily scrubs an inactive raw context. Without an earlier scrub, the row copy carrying that context becomes expiry-eligible within 14 days of the last save that carried it. Expired rows are then removed by bounded periodic cleanup, so physical deletion can follow with an operational lag. Raw Google Analytics identifiers are not copied into OAuth state.
Unknown or rejected consent sends no optional analytics request. Analytics-only consent grants analytics storage while advertising storage and advertising-user-data access remain denied. The separate click-measurement choice grants those two advertising measurement signals, but advertising personalization remains denied in every case. RunYour.App does not send payment or revenue events. The version 3 consent choice expires after 180 days. A downgrade or withdrawal immediately disables the affected measurement locally. Other open same-origin tabs receive an ephemeral browser-storage signal where available and otherwise reconcile on focus or visibility; a tagged receiving tab applies denied status, removes the affected Google cookies and click IDs, and reloads. The initiating tab requests immediate revocation of the stored server context and waits for confirmation before reloading after a full withdrawal or restoring analytics-only operation after a downgrade. Its server-side consent generation prevents an older analytics request from restoring consent. An unreachable context also expires after 30 minutes unless refreshed.
Recipients and international transfers
RunYour.App uses GitHub for identity, source access, and GHCR packages; Google Analytics for consented measurement; Microsoft Advertising for a consented offline conversion after a verified deployment; YouTube to deliver the product demo only after you choose to play it; Hetzner infrastructure located in Germany for server compute and networking; and providers required for private object storage, communications, security, and professional advice. The privacy-enhanced YouTube frame is absent before that choice. On playback, YouTube receives the request and accompanying technical data under Google's terms. A Google Ads conversion import is not currently verified or active; if the gated integration is later activated, Google Ads will receive the planned conversion reporting imported from linked GA4. Microsoft receives the validated click ID and bounded conversion facts only through the reviewed offline upload path; RunYour.App does not load Microsoft browser code. Read the Microsoft Privacy Statement. Providers receive only the information needed for their function and act under their own terms or appropriate processing arrangements.
A provider may process information outside the European Economic Area. Where required, transfers rely on an applicable adequacy decision or contractual and supplementary safeguards. Contact us for information about the safeguard relevant to a particular transfer.
Credentials and runtime values are encrypted at rest. Access is limited to the service paths that need it.
Retention and deletion
Source snapshots are scheduled for deletion after seven days. Project records, derived artifacts, credentials, and platform-managed resources are retained while needed to operate the relevant account or project and are queued for cleanup when the project is deleted or the authority is revoked.
GHCR packages are owned by your GitHub account and are not deleted by RunYour.App. You must remove them in GitHub. You can revoke the OAuth grant and personal access token in GitHub at any time.
Security, support, moderation, transaction, and audit records are retained only as long as reasonably needed for the stated purpose, applicable limitation periods, or a legal obligation. Residual copies may remain until protected backups rotate. Retention is also limited by storage integrity and the need to investigate abuse or disputes.
A consented raw Microsoft click ID is kept in its dedicated encrypted attribution record for no more than 30 days. It is deleted earlier after explicit withdrawal or revocation, expiry of the Microsoft attribution consent decision, account deletion, or when the corresponding Apply upload is acknowledged without a per-item error. Decision expiry also suppresses nonterminal conversions. The separate 30-minute analytics-context authorization expiry is not by itself a physical-deletion promise for an already bound click ID. That acknowledgment is not proof of attribution or Microsoft reporting. A keyed digest and bounded status/timing evidence may remain only to enforce first-only and retry idempotency; they cannot be used to recover the raw click ID.
RunYour.App's pseudonymous internal product-analytics event and delivery-outbox rows have a configured 60-day retention horizon. After the creation-time cutoff they become eligible for bounded periodic purge, so physical deletion can follow with an operational lag. These rows can include Google Analytics client and optional session identifiers, random analytics event or subject UUIDs where applicable, and the one-way browser-session-key HMAC stored with relayed browser events. They can also include the advertising-user-data consent status captured for an event, but not a raw Google Ads click identifier. That HMAC is not sent to Google Analytics. Immutable projection markers may remain to prevent old pipeline events from being captured again, but they do not retain those Google Analytics identifiers or event payloads. The account-level marker that prevents a later verified deployment from being misclassified as the first may remain until account deletion; it contains a timestamp and optional source-event pointer, but no Google Analytics identifier or click ID. The source pointer is cleared if its pipeline record is deleted. Decision-to-session HMAC links follow the shorter decision lifetime and cascade when an expired decision is purged. Expired server-session rows are cleaned in a separate bounded process.
Google Analytics is configured to retain event data for two months and user data for fourteen months, with the user-data period reset on new activity. These settings do not delete standard aggregated Google Analytics reports.
Your rights
Subject to applicable conditions, you may request access, rectification, erasure, restriction, portability, or object to processing based on legitimate interests. You may also complain to the Spanish Data Protection Agency (AEPD) or another competent supervisory authority.
Send requests or privacy questions to [email protected]. We may need to verify your identity. Do not include credentials or private repository content in email.
Required information and automated decisions
GitHub identity, an authentication grant, selected source, and required credentials are necessary to provide the corresponding functions; without them those functions cannot work. RunYour.App does not use your personal data for solely automated decisions that produce legal or similarly significant effects.