mirror of
https://tangled.org/evan.jarrett.net/at-container-registry
synced 2026-08-31 13:17:09 +00:00
347 lines
22 KiB
HTML
347 lines
22 KiB
HTML
{{ define "privacy" }}
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
{{ template "head" . }}
|
|
{{ template "meta" .Meta }}
|
|
</head>
|
|
<body>
|
|
{{ template "nav" . }}
|
|
|
|
<main class="container mx-auto px-4 py-8 max-w-4xl">
|
|
<h1 class="text-3xl font-bold mb-2">Privacy Policy - {{ .CompanyName }} ({{ .SiteURL }})</h1>
|
|
<p class="text-base-content/60 mb-8"><em>Last updated: January 2025</em></p>
|
|
|
|
<div class="prose prose-sm max-w-none space-y-8">
|
|
<section>
|
|
<h2 class="text-xl font-semibold text-primary">Data We Collect and Store</h2>
|
|
|
|
<h3 class="text-lg font-medium mt-4">Data Stored on Your PDS (Controlled by You)</h3>
|
|
<p>When you use {{ .CompanyName }}, records are written to your Personal Data Server (PDS) under the <code class="bg-base-200 px-1.5 py-0.5 rounded text-sm font-mono">io.atcr.*</code> namespace. This data is stored on infrastructure you or your PDS hosting provider controls. We do not control this data, and its retention and deletion is governed by your PDS provider's policies.</p>
|
|
|
|
<h3 class="text-lg font-medium mt-6">Data Stored on Our Infrastructure</h3>
|
|
|
|
<p><strong>Layer Records:</strong> Our hold services (e.g., <code class="bg-base-200 px-1.5 py-0.5 rounded text-sm font-mono">hold01.{{ .SiteURL }}</code>) maintain records in their embedded PDS that reference container image layers you publish. These records are public and link your AT Protocol identity (DID) to content-addressed SHA identifiers.</p>
|
|
|
|
<p><strong>OCI Blobs:</strong> Container image layers are stored in our object storage (S3). These blobs are content-addressed and deduplicated—meaning identical layers uploaded by different users are stored only once.</p>
|
|
|
|
<p><strong>Authentication Data:</strong></p>
|
|
<ul class="list-disc list-inside space-y-1 ml-4">
|
|
<li>OAuth tokens obtained during sign-in</li>
|
|
<li>Web UI session tokens</li>
|
|
<li>Docker credential helper device tokens, including:
|
|
<ul class="list-disc list-inside ml-6 mt-1 space-y-1">
|
|
<li>IP address</li>
|
|
<li>Device name</li>
|
|
<li>Token creation and last-used timestamps</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
|
|
<p class="mt-4"><strong>Cached PDS Data:</strong> We may cache data from your PDS in our database to improve performance and reduce load on your PDS. This cached data mirrors public information already stored on your PDS.</p>
|
|
|
|
<p><strong>Server Logs:</strong> Our logs may include your handle, DID, IP address, timestamps, and actions performed. Logs are currently ephemeral but may be retained in the future for security and debugging purposes.</p>
|
|
</section>
|
|
|
|
<section>
|
|
<h2 class="text-xl font-semibold text-primary">Our Services and Their Data</h2>
|
|
|
|
<p>{{ .CompanyName }} consists of multiple services, each with distinct data responsibilities:</p>
|
|
|
|
<h3 class="text-lg font-medium mt-4">AppView ({{ .SiteURL }})</h3>
|
|
<p>The registry frontend you interact with directly. Stores:</p>
|
|
<ul class="list-disc list-inside space-y-1 ml-4">
|
|
<li>OAuth sessions and tokens for authentication</li>
|
|
<li>Device tokens for the Docker credential helper</li>
|
|
<li>Web UI sessions</li>
|
|
<li>Cached metadata from your PDS (indexes for search and display)</li>
|
|
</ul>
|
|
|
|
<h3 class="text-lg font-medium mt-6">{{ .ClientShortName }}-Hosted Hold Services</h3>
|
|
<p>Storage backends we operate (e.g., <code class="bg-base-200 px-1.5 py-0.5 rounded text-sm font-mono">hold01.{{ .SiteURL }}</code>). Each hold has an embedded PDS and stores:</p>
|
|
<ul class="list-disc list-inside space-y-1 ml-4">
|
|
<li>OCI blobs (container image layers) in object storage</li>
|
|
<li>Layer records in the hold's embedded PDS linking your DID to blob references</li>
|
|
<li>Crew membership records for access control</li>
|
|
</ul>
|
|
<p class="mt-2">Hold services on <code class="bg-base-200 px-1.5 py-0.5 rounded text-sm font-mono">*.{{ .SiteURL }}</code> domains are operated by us and covered by this policy.</p>
|
|
|
|
<h3 class="text-lg font-medium mt-6">User-Deployed Hold Services (BYOS)</h3>
|
|
<p>You may use "Bring Your Own Storage" by deploying your own hold service. Data on user-deployed holds is governed by that operator's privacy policy, not ours. We can request deletion on your behalf but cannot guarantee it for services we do not control.</p>
|
|
</section>
|
|
|
|
<section>
|
|
<h2 class="text-xl font-semibold text-primary">Data Sharing and Deduplication</h2>
|
|
|
|
<p>OCI container images use content-addressable storage. When you push an image layer, it is identified by its cryptographic hash (SHA256). If another user pushes an identical layer, both users reference the same underlying blob. This is standard practice for container registries and enables efficient storage and distribution.</p>
|
|
|
|
<p><strong>What this means for your data:</strong></p>
|
|
<ul class="list-disc list-inside space-y-1 ml-4">
|
|
<li>Layer content is not uniquely "yours" if other users have pushed identical content</li>
|
|
<li>Public SHA references may be associated with your AT Protocol identity</li>
|
|
<li>Deleting your records does not delete blob data that other users also reference</li>
|
|
</ul>
|
|
</section>
|
|
|
|
<section>
|
|
<h2 class="text-xl font-semibold text-primary">Your Rights Under GDPR</h2>
|
|
|
|
<p>If you are located in the European Economic Area (EEA), you have the following rights:</p>
|
|
|
|
<h3 class="text-lg font-medium mt-4">Right to Access</h3>
|
|
<p>You may export a copy of all personal data we store about you via the "Export Data" button in your account settings. This export includes:</p>
|
|
<ul class="list-disc list-inside space-y-1 ml-4">
|
|
<li>Layer records associated with your DID on our PDS</li>
|
|
<li>OAuth tokens, web UI sessions, and device tokens</li>
|
|
<li>Cached PDS data</li>
|
|
<li>List of registered devices (credential helper)</li>
|
|
</ul>
|
|
<p class="mt-2">For data not included in the self-service export (such as server logs), contact us and we will respond within 30 days.</p>
|
|
<p class="text-base-content/70 text-sm mt-2">Note: Data stored on your own PDS is already under your control and accessible to you directly.</p>
|
|
|
|
<h3 class="text-lg font-medium mt-6">Right to Erasure ("Right to be Forgotten")</h3>
|
|
<p>You may request deletion of your data via the account settings page. Due to our technical architecture, deletion works as follows:</p>
|
|
|
|
<p class="mt-4"><strong>Immediately deleted from AppView:</strong></p>
|
|
<ul class="list-disc list-inside space-y-1 ml-4">
|
|
<li>OAuth tokens, web UI sessions, and device tokens</li>
|
|
<li>Cached PDS data (manifest and tag indexes)</li>
|
|
<li>Server logs containing your identifiers (deleted or anonymized, if retained)</li>
|
|
</ul>
|
|
|
|
<p class="mt-4"><strong>Immediately deleted from {{ .CompanyName }}-hosted holds:</strong></p>
|
|
<ul class="list-disc list-inside space-y-1 ml-4">
|
|
<li>Layer records in the hold's embedded PDS that reference your DID</li>
|
|
<li>Crew membership records</li>
|
|
</ul>
|
|
|
|
<p class="mt-4"><strong>Deleted within 30 days from {{ .CompanyName }}-hosted holds:</strong></p>
|
|
<ul class="list-disc list-inside space-y-1 ml-4">
|
|
<li>OCI blobs in object storage that are no longer referenced by any user (via garbage collection)</li>
|
|
</ul>
|
|
|
|
<p class="mt-4"><strong>User-deployed holds:</strong></p>
|
|
<ul class="list-disc list-inside space-y-1 ml-4">
|
|
<li>We attempt to delete your data via API, but success depends on hold availability</li>
|
|
<li>Data on holds we do not operate is governed by that operator's policies</li>
|
|
</ul>
|
|
|
|
<p class="mt-4"><strong>Cannot be deleted by us:</strong></p>
|
|
<ul class="list-disc list-inside space-y-1 ml-4">
|
|
<li>Records stored on your own PDS (you control these, or your PDS provider does)</li>
|
|
<li>Blob data that is also referenced by other users (deduplicated content)</li>
|
|
</ul>
|
|
|
|
<p class="mt-4"><strong>Optional: Delete AT Protocol Records</strong></p>
|
|
<p>When deleting your account, you may optionally authorize us to delete <code class="bg-base-200 px-1.5 py-0.5 rounded text-sm font-mono">io.atcr.*</code> records from your PDS. This requires an active OAuth session and is optional because:</p>
|
|
<ul class="list-disc list-inside space-y-1 ml-4">
|
|
<li>Your PDS is controlled by you or your hosting provider, not us</li>
|
|
<li>You may delete these records yourself at any time</li>
|
|
<li>We have no ongoing obligation to manage data on infrastructure we do not control</li>
|
|
</ul>
|
|
|
|
<h3 class="text-lg font-medium mt-6">Right to Rectification</h3>
|
|
<p>You may update your data through normal use of the service. Data stored on your PDS is under your direct control.</p>
|
|
|
|
<h3 class="text-lg font-medium mt-6">Right to Data Portability</h3>
|
|
<p>AT Protocol is designed for data portability. Your records are stored in an open, documented format on your PDS and can be exported or migrated at any time.</p>
|
|
|
|
<h3 class="text-lg font-medium mt-6">Right to Object / Restrict Processing</h3>
|
|
<p>You may revoke our OAuth access at any time through your PDS provider's settings. This will prevent us from reading or writing records to your PDS.</p>
|
|
</section>
|
|
|
|
<section>
|
|
<h2 class="text-xl font-semibold text-primary">Your Rights Under CCPA</h2>
|
|
|
|
<p>If you are a California resident, you have the following rights under the California Consumer Privacy Act:</p>
|
|
|
|
<h3 class="text-lg font-medium mt-4">Right to Know</h3>
|
|
<p>You may export a copy of your personal data via the "Export Data" button in your account settings. You may also request disclosure of:</p>
|
|
<ul class="list-disc list-inside space-y-1 ml-4">
|
|
<li>The categories of personal information we collect</li>
|
|
<li>The purposes for which we use your personal information</li>
|
|
<li>The categories of third parties with whom we share your personal information</li>
|
|
</ul>
|
|
<p class="mt-2">For data not included in the self-service export (such as server logs), contact us and we will respond within 30 days.</p>
|
|
|
|
<h3 class="text-lg font-medium mt-6">Right to Delete</h3>
|
|
<p>You may delete your personal information via the account settings page, subject to the same technical limitations described in the GDPR section above. For data not accessible through self-service, we will respond to requests within 45 days, except where retention is necessary for:</p>
|
|
<ul class="list-disc list-inside space-y-1 ml-4">
|
|
<li>Completing the transaction for which the data was collected</li>
|
|
<li>Security and fraud prevention</li>
|
|
<li>Legal compliance</li>
|
|
</ul>
|
|
|
|
<h3 class="text-lg font-medium mt-6">Right to Non-Discrimination</h3>
|
|
<p>We will not discriminate against you for exercising your CCPA rights.</p>
|
|
|
|
<h3 class="text-lg font-medium mt-6">Categories of Personal Information Collected</h3>
|
|
<div class="overflow-x-auto mt-4">
|
|
<table class="table table-zebra w-full">
|
|
<thead>
|
|
<tr>
|
|
<th>Category</th>
|
|
<th>Examples</th>
|
|
<th>Collected</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>Identifiers</td>
|
|
<td>DID, handle, IP address, device name</td>
|
|
<td>Yes</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Internet activity</td>
|
|
<td>Access logs, usage data, actions performed</td>
|
|
<td>Yes</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Geolocation</td>
|
|
<td>Approximate location via IP</td>
|
|
<td>Yes</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<p class="mt-4">We do not sell or share your personal information for cross-context behavioral advertising.</p>
|
|
</section>
|
|
|
|
<section>
|
|
<h2 class="text-xl font-semibold text-primary">Data Retention</h2>
|
|
|
|
<div class="overflow-x-auto mt-4">
|
|
<table class="table table-zebra w-full">
|
|
<thead>
|
|
<tr>
|
|
<th>Data Type</th>
|
|
<th>Service</th>
|
|
<th>Retention Period</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>OAuth tokens</td>
|
|
<td>AppView</td>
|
|
<td>Until revoked or logout</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Web UI session tokens</td>
|
|
<td>AppView</td>
|
|
<td>Until logout or expiration</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Device tokens (credential helper)</td>
|
|
<td>AppView</td>
|
|
<td>Until revoked by user</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Cached PDS data</td>
|
|
<td>AppView</td>
|
|
<td>Refreshed periodically; deleted on account deletion</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Server logs</td>
|
|
<td>AppView</td>
|
|
<td>Currently ephemeral; this policy will be updated if log retention is implemented</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Layer records</td>
|
|
<td>Hold PDS</td>
|
|
<td>Until you request deletion</td>
|
|
</tr>
|
|
<tr>
|
|
<td>OCI blobs</td>
|
|
<td>Hold Storage</td>
|
|
<td>Until no longer referenced (pruned within 30 days)</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</section>
|
|
|
|
<section>
|
|
<h2 class="text-xl font-semibold text-primary">Important Notes on AT Protocol Architecture</h2>
|
|
|
|
<p>{{ .CompanyName }} is built on the AT Protocol, which has a unique data architecture:</p>
|
|
|
|
<ol class="list-decimal list-inside space-y-2 ml-4 mt-4">
|
|
<li><strong>You control your data.</strong> Most data associated with your use of {{ .CompanyName }} is stored on your Personal Data Server (PDS), which you or your chosen provider controls.</li>
|
|
<li><strong>Public by design.</strong> AT Protocol data is designed to be public and distributed. Records you create, including container image references, are publicly visible and may be replicated across the network.</li>
|
|
<li><strong>Content-addressed storage.</strong> OCI blobs are identified by their cryptographic hash. This means blob data is inherently pseudonymous—it cannot be attributed to you without the corresponding records that reference it.</li>
|
|
<li><strong>Deletion limitations.</strong> Because AT Protocol is distributed, we cannot guarantee that copies of public records have not been made by other participants in the network. We can only delete data on infrastructure we control.</li>
|
|
</ol>
|
|
</section>
|
|
|
|
<section>
|
|
<h2 class="text-xl font-semibold text-primary">Bring Your Own Storage (BYOS)</h2>
|
|
|
|
<p>{{ .CompanyName }} supports "Bring Your Own Storage" where users can deploy their own hold services to store container image blobs. This section explains how BYOS affects your privacy rights.</p>
|
|
|
|
<h3 class="text-lg font-medium mt-4">{{ .CompanyName }}-Hosted Holds</h3>
|
|
<p>Hold services on <code class="bg-base-200 px-1.5 py-0.5 rounded text-sm font-mono">*.{{ .SiteURL }}</code> domains (e.g., <code class="bg-base-200 px-1.5 py-0.5 rounded text-sm font-mono">hold01.{{ .SiteURL }}</code>) are operated by us and fully covered by this privacy policy. We can fulfill all data access, export, and deletion requests for these services.</p>
|
|
|
|
<h3 class="text-lg font-medium mt-6">User-Deployed Holds</h3>
|
|
<p>If you use a hold service not operated by us:</p>
|
|
<ul class="list-disc list-inside space-y-1 ml-4">
|
|
<li>That hold's data practices are governed by its operator's privacy policy, not ours</li>
|
|
<li>When you request account deletion, we attempt to delete your data from all holds via API</li>
|
|
<li>We cannot guarantee deletion for holds that are offline or refuse the request</li>
|
|
<li>You should contact that hold's operator directly for data requests we cannot fulfill</li>
|
|
</ul>
|
|
|
|
<h3 class="text-lg font-medium mt-6">If You Operate a Hold</h3>
|
|
<p>If you deploy your own hold service and allow other users to store data on it, you become a data controller for that data under GDPR/CCPA. You are responsible for:</p>
|
|
<ul class="list-disc list-inside space-y-1 ml-4">
|
|
<li>Responding to deletion requests from users of your hold</li>
|
|
<li>Implementing appropriate data retention policies</li>
|
|
<li>Publishing your own privacy policy if required by law</li>
|
|
</ul>
|
|
</section>
|
|
|
|
<section>
|
|
<h2 class="text-xl font-semibold text-primary">How to Exercise Your Rights</h2>
|
|
|
|
<h3 class="text-lg font-medium mt-4">Self-Service (via Settings)</h3>
|
|
<p>Most data management can be done directly through your account settings at {{ .SiteURL }}:</p>
|
|
<ul class="list-disc list-inside space-y-1 ml-4">
|
|
<li><strong>Export your data:</strong> Use the "Export Data" button in settings to download a copy of all personal data we store about you.</li>
|
|
<li><strong>Delete your data:</strong> Use the "Delete Account" button in settings. This will remove your layer records, cached data, and authentication tokens. You may also choose to have us delete <code class="bg-base-200 px-1.5 py-0.5 rounded text-sm font-mono">io.atcr.*</code> records from your PDS (requires active OAuth session).</li>
|
|
<li><strong>Revoke device tokens:</strong> Manage and revoke credential helper devices in settings.</li>
|
|
<li><strong>Update your data:</strong> Corrections happen through normal use of the service.</li>
|
|
</ul>
|
|
|
|
<h3 class="text-lg font-medium mt-6">Contact Us</h3>
|
|
<p>For requests we cannot fulfill through self-service, such as:</p>
|
|
<ul class="list-disc list-inside space-y-1 ml-4">
|
|
<li>Copies of server logs containing your data</li>
|
|
<li>Database records not exposed in the UI</li>
|
|
<li>Questions about this policy</li>
|
|
</ul>
|
|
|
|
<p class="mt-4"><strong>Email:</strong> <a href="mailto:privacy@{{ .SiteURL }}" class="link link-primary">privacy@{{ .SiteURL }}</a></p>
|
|
|
|
<p class="mt-2">Please include your AT Protocol DID or handle so we can verify your identity.</p>
|
|
|
|
<p class="mt-2">We will respond to requests within 30 days (GDPR) or 45 days (CCPA).</p>
|
|
</section>
|
|
|
|
<section>
|
|
<h2 class="text-xl font-semibold text-primary">Contact</h2>
|
|
|
|
<p>For questions about this privacy policy or to exercise your data rights, contact:</p>
|
|
|
|
<p class="mt-4"><strong>Email:</strong> <a href="mailto:privacy@{{ .SiteURL }}" class="link link-primary">privacy@{{ .SiteURL }}</a></p>
|
|
<p><strong>Website:</strong> <a href="https://{{ .SiteURL }}" class="link link-primary">https://{{ .SiteURL }}</a></p>
|
|
</section>
|
|
</div>
|
|
</main>
|
|
|
|
<div id="modal"></div>
|
|
|
|
{{ template "footer" . }}
|
|
</body>
|
|
</html>
|
|
{{ end }}
|