<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Exporting and importing on back(d)</title><link>https://fernandezvara.github.io/backd/docs/operate/administration/export-import/</link><description>Recent content in Exporting and importing on back(d)</description><generator>Hugo</generator><language>en-us</language><atom:link href="https://fernandezvara.github.io/backd/docs/operate/administration/export-import/index.xml" rel="self" type="application/rss+xml"/><item><title>Moving an app between instances</title><link>https://fernandezvara.github.io/backd/docs/operate/administration/export-import/moving-an-app/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fernandezvara.github.io/backd/docs/operate/administration/export-import/moving-an-app/</guid><description>&lt;p&gt;This is the whole journey of moving an app, users included, from an instance you call &lt;em&gt;old&lt;/em&gt; to one you call &lt;em&gt;new&lt;/em&gt;.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Prepare the new instance.&lt;/strong&gt; Its &lt;code&gt;CONFIG_DIR&lt;/code&gt; needs the same databases and collections as the old one (the schemas may differ: the import tells you what the new ones refuse). Provision it (&lt;code&gt;backd-server provision&lt;/code&gt;, or start it) and make sure the realm has authentication enabled and, if documents hold files, a &lt;code&gt;storage:&lt;/code&gt; section (and a &lt;code&gt;public_storage:&lt;/code&gt; one if they hold &lt;a href="../../../../build/files/file-fields/#public-fields"&gt;public files&lt;/a&gt;) whose secrets are set.&lt;/p&gt;</description></item><item><title>Seeding staging</title><link>https://fernandezvara.github.io/backd/docs/operate/administration/export-import/seeding-staging/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fernandezvara.github.io/backd/docs/operate/administration/export-import/seeding-staging/</guid><description>&lt;p&gt;A staging or test instance is only as safe as the data in it. This page is about making that data with &lt;code&gt;backd export --anonymize&lt;/code&gt;; the import is the one of &lt;a href="../moving-an-app/#importing"&gt;moving an app&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A staging or test instance is only as safe as the data in it. &lt;code&gt;--anonymize&lt;/code&gt; turns an export into a copy that holds no real person&amp;rsquo;s details, using what you already declared for &lt;a href="../../erasure/"&gt;erasing a user&lt;/a&gt;:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;backd export --realm clinic --include auth --anonymize --anonymize-config staging.yaml \
 --staging-password env:STAGING_PASS --out ./clinic-staging
backd import --realm clinic --from ./clinic-staging # on the staging instance
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Collections.&lt;/strong&gt; Each collection&amp;rsquo;s &lt;a href="../../erasure/"&gt;&lt;code&gt;on_owner_delete&lt;/code&gt;&lt;/a&gt; &lt;code&gt;remove&lt;/code&gt; and &lt;code&gt;replace&lt;/code&gt; are applied to &lt;strong&gt;every&lt;/strong&gt; document, whoever owns it. They were already checked against the schema, so the documents stay valid. The fields of &lt;code&gt;pull&lt;/code&gt; and &lt;code&gt;unset&lt;/code&gt; that hold an &lt;strong&gt;email&lt;/strong&gt; are rewritten with the same addresses as the users&amp;rsquo; (an address that belongs to no user becomes &lt;code&gt;unknown-&amp;lt;hash&amp;gt;@example.invalid&lt;/code&gt;). A collection without a policy is exported as it is: write one, or use the override file.&lt;/p&gt;</description></item><item><title>Encrypted fields</title><link>https://fernandezvara.github.io/backd/docs/operate/administration/export-import/encrypted-fields/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fernandezvara.github.io/backd/docs/operate/administration/export-import/encrypted-fields/</guid><description>&lt;p&gt;&lt;a href="../../../../build/configuration/field-keys/"&gt;Encrypted fields&lt;/a&gt; are there so that a dump, a backup or a package can&amp;rsquo;t be read without their keys. An export keeps that promise: &lt;strong&gt;the server never decrypts for an export.&lt;/strong&gt; Whatever you can read of an encrypted field in a package, you read because &lt;strong&gt;you&lt;/strong&gt; supplied its key, in the command on your machine.&lt;/p&gt;
&lt;h2 id="what-a-package-holds"&gt;What a package holds&lt;a class="hd-anchor" href="#what-a-package-holds" aria-hidden="true"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;backd export --realm clinic --out ./clinic
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Every encrypted value is in the package as it is stored (ciphertext), with &lt;code&gt;_system/data_keys.jsonl&lt;/code&gt;, the wrapped data and index keys of those fields, and the manifest lists each field with the &lt;strong&gt;name and fingerprint of its key&lt;/strong&gt; and its form:&lt;/p&gt;</description></item><item><title>Reporting extracts and CSV</title><link>https://fernandezvara.github.io/backd/docs/operate/administration/export-import/reporting-extracts/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fernandezvara.github.io/backd/docs/operate/administration/export-import/reporting-extracts/</guid><description>&lt;p&gt;To hand an analyst a table, not a package, narrow the export and ask for CSV:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;backd export --realm clinic --db main --collection patients \
 --fields name,birth_year,address --where &amp;#39;{&amp;#34;status&amp;#34;: &amp;#34;active&amp;#34;}&amp;#39; \
 --format csv --out ./active-patients
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;--fields&lt;/code&gt;&lt;/strong&gt; keeps only those paths of every document (&lt;code&gt;id&lt;/code&gt; is always there; &lt;code&gt;_meta.owner&lt;/code&gt; and the other &lt;code&gt;_meta&lt;/code&gt; fields can be asked for, and are left out otherwise). A name that is an object, like &lt;code&gt;address&lt;/code&gt;, keeps all of it. A path that exists in none of the exported collections is refused. A package made with &lt;code&gt;--fields&lt;/code&gt; is marked &lt;strong&gt;partial&lt;/strong&gt; in its manifest.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;--where&lt;/code&gt;&lt;/strong&gt; takes the same JSON filter as the data API&amp;rsquo;s &lt;a href="../../../../build/api/querying/#where"&gt;&lt;code&gt;where&lt;/code&gt;&lt;/a&gt; and needs &lt;code&gt;--db&lt;/code&gt; and exactly one &lt;code&gt;--collection&lt;/code&gt;. It is checked against the collection&amp;rsquo;s schema before anything is read; documents in the trash match like any other.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;--format csv&lt;/code&gt;&lt;/strong&gt; writes &lt;code&gt;&amp;lt;database&amp;gt;/&amp;lt;collection&amp;gt;.csv&lt;/code&gt;, one RFC 4180 file per collection, and a manifest with their checksums. No system data and no files go in it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The CSV is a &lt;strong&gt;flat view and loses information&lt;/strong&gt;, so it can never be imported:&lt;/p&gt;</description></item><item><title>Direct mode: without a running backd</title><link>https://fernandezvara.github.io/backd/docs/operate/administration/export-import/direct-mode/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fernandezvara.github.io/backd/docs/operate/administration/export-import/direct-mode/</guid><description>&lt;p&gt;&lt;a href="../../server/"&gt;&lt;code&gt;backd-server&lt;/code&gt;&lt;/a&gt;&amp;rsquo;s &lt;code&gt;export&lt;/code&gt; and &lt;code&gt;import&lt;/code&gt; run the same export and import as the CLI&amp;rsquo;s &lt;strong&gt;in the command itself&lt;/strong&gt;, straight on MongoDB and &lt;code&gt;CONFIG_DIR&lt;/code&gt;, with no running server: use them when the server is stopped or can&amp;rsquo;t be reached, or to read a backup. They take the CLI&amp;rsquo;s flags, plus these:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;backd-server export --mongo-uri env:MONGO_URI --realm clinic --no-files --out ./clinic-offline
backd-server import --mongo-uri env:MONGO_URI --realm clinic --from ./clinic-offline
&lt;/code&gt;&lt;/pre&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Flag&lt;/th&gt;
 &lt;th&gt;Meaning&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;--mongo-uri&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;The MongoDB URI, or &lt;code&gt;env:&amp;lt;VAR&amp;gt;&lt;/code&gt; / &lt;code&gt;file:&amp;lt;path&amp;gt;&lt;/code&gt;; default &lt;code&gt;BACKD_MONGO_URI&lt;/code&gt;, then &lt;code&gt;MONGO_URI&lt;/code&gt; (&lt;code&gt;CONFIG_DIR&lt;/code&gt; is the environment variable, as for &lt;code&gt;serve&lt;/code&gt;)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;--master-key&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;The secrets master key (&lt;code&gt;env:&lt;/code&gt; / &lt;code&gt;file:&lt;/code&gt;); default &lt;code&gt;BACKD_SECRETS_KEY&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;--storage-key&lt;/code&gt;, &lt;code&gt;--storage-secret&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;The storage credentials, instead of the realm&amp;rsquo;s secrets (&lt;code&gt;env:&lt;/code&gt; / &lt;code&gt;file:&lt;/code&gt;)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;--public-storage-key&lt;/code&gt;, &lt;code&gt;--public-storage-secret&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;The same for the realm&amp;rsquo;s &lt;a href="../../../providers/storage/#public-storage"&gt;public storage&lt;/a&gt;, if it has one&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;--force&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Import while an instance serves the realm&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;What it needs.&lt;/strong&gt; &lt;code&gt;CONFIG_DIR&lt;/code&gt; is read to know the schemas, the file fields and the indexes; the functions&amp;rsquo; bundles are not built, so no Deno is needed. The realm must have authentication enabled. The command validates and writes exactly as the network path does, and nothing is provisioned or changed in MongoDB&amp;rsquo;s structure.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The master key is not needed for data.&lt;/strong&gt; It &lt;strong&gt;is&lt;/strong&gt; needed for two things: &lt;strong&gt;files&lt;/strong&gt;, because the storage credentials are realm secrets (give &lt;code&gt;--storage-key&lt;/code&gt; and &lt;code&gt;--storage-secret&lt;/code&gt;, and the &lt;code&gt;--public-storage-*&lt;/code&gt; pair for public files, instead, or leave files out with &lt;code&gt;--no-files&lt;/code&gt;), and the &lt;strong&gt;authentication data sealed by the realm&lt;/strong&gt; (authenticator secrets, push device tokens, Apple tokens) with &lt;code&gt;--include auth&lt;/code&gt;: without &lt;code&gt;--master-key&lt;/code&gt; they stay behind and the command says how many.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Refuses while the realm is served.&lt;/strong&gt; Every &lt;code&gt;backd-server serve&lt;/code&gt; records a heartbeat in MongoDB (&lt;code&gt;backd___deployment.instances&lt;/code&gt;, every 15 seconds); an offline import will not write while an instance that serves the realm was heard from in the last 45 seconds, because two writers could clash. &lt;code&gt;--force&lt;/code&gt; writes anyway, with a warning. An export only reads and never refuses, but it is not a snapshot while the realm is being written.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Audited, as offline.&lt;/strong&gt; The records go into the realm&amp;rsquo;s audit trail with the actor &lt;code&gt;cli:offline&lt;/code&gt; and &lt;code&gt;offline: true&lt;/code&gt;, like any other.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No credentials are asked for.&lt;/strong&gt; Whoever holds MongoDB and the configuration already holds more than any admin account: protect that access accordingly.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="reading-an-old-backup"&gt;Reading an old backup&lt;a class="hd-anchor" href="#reading-an-old-backup" aria-hidden="true"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;You do not need a separate tool to read a &lt;code&gt;mongodump&lt;/code&gt;: restore it into any MongoDB with &lt;code&gt;mongorestore&lt;/code&gt;, point &lt;code&gt;--mongo-uri&lt;/code&gt; at it and run &lt;code&gt;backd-server export&lt;/code&gt; with the configuration the backup was made under. The result is an ordinary package you can inspect, import into another instance or hand to an analyst as CSV.&lt;/p&gt;</description></item><item><title>Reference</title><link>https://fernandezvara.github.io/backd/docs/operate/administration/export-import/reference/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fernandezvara.github.io/backd/docs/operate/administration/export-import/reference/</guid><description>&lt;p&gt;Everything about the commands, in one place: the package format, every flag, the admin API and what to do about each error.&lt;/p&gt;
&lt;h2 id="the-package"&gt;The package&lt;a class="hd-anchor" href="#the-package" aria-hidden="true"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;A package is a directory, or one &lt;code&gt;.tar.gz&lt;/code&gt; of it (&lt;code&gt;--archive&lt;/code&gt;). All paths are relative, with no &lt;code&gt;..&lt;/code&gt;, and the whole is verified against &lt;code&gt;manifest.json&lt;/code&gt; before an import uses any of it.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;clinic-2026-10-09/
 manifest.json
 main/patients.jsonl one file per collection
 main/visits.jsonl
 main/_files/&amp;lt;file id&amp;gt; the object of every file the documents reference (private and public)
 _system/data_keys.jsonl wrapped keys of encrypted fields (empty without any)
 _system/auth/users.jsonl only with --include auth
 _system/auth/identities.jsonl … orgs, org_members, org_teams, org_connections, mfa, devices
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="manifestjson"&gt;manifest.json&lt;a class="hd-anchor" href="#manifestjson" aria-hidden="true"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;format&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;backd_version&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;v0.10.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;realm&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;clinic&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;created_at&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2026-10-09T10:15:00Z&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;operator&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;key:svc&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;config_fingerprint&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;9f2c…&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;flags&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;partial&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;anonymized&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;auth&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;no_files&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;csv&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;databases&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;main&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;collections&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;patients&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;documents&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1204&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;part&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;main/patients.jsonl&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;encrypted_fields&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;database&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;main&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;collection&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;patients&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;path&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;notes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;HEALTH&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;fingerprint&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;9f2c41d0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;form&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;ciphertext&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;auth&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;users&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;documents&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;part&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;_system/auth/users.jsonl&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;auth_key_fingerprint&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;6f42f0e47d8b8cc9&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;files&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;87&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;checksums&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;main/patients.jsonl&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;sha256:ba78…&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;main/_files/fl_0123456789abcdefghij&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;sha256:2c26…&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Field&lt;/th&gt;
 &lt;th&gt;Meaning&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;format&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;The package layout version. An import refuses a format it doesn&amp;rsquo;t know&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;backd_version&lt;/code&gt;, &lt;code&gt;realm&lt;/code&gt;, &lt;code&gt;created_at&lt;/code&gt;, &lt;code&gt;operator&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Where and by whom it was made; &lt;code&gt;operator&lt;/code&gt; is &lt;code&gt;cli:offline&lt;/code&gt; for a &lt;a href="../direct-mode/"&gt;direct&lt;/a&gt; export&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;config_fingerprint&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Of the configuration it was made under; a different one on import is a warning&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;flags.partial&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Made with &lt;code&gt;--fields&lt;/code&gt;: an import refuses it&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;flags.csv&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;A &lt;a href="../reporting-extracts/"&gt;CSV extract&lt;/a&gt;: an import refuses it&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;flags.anonymized&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;A &lt;a href="../seeding-staging/"&gt;staging copy&lt;/a&gt;; an import compares it with &lt;code&gt;BACKD_ENV&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;flags.auth&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Holds authentication data (the &lt;code&gt;auth&lt;/code&gt; parts)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;flags.no_files&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Made without files (&lt;code&gt;--no-files&lt;/code&gt;, an anonymized or CSV export)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;databases[].collections[]&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Each collection&amp;rsquo;s document count and the package path of its documents&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;encrypted_fields[]&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Each &lt;a href="../encrypted-fields/"&gt;encrypted field&lt;/a&gt;: its &lt;code&gt;database&lt;/code&gt;, &lt;code&gt;collection&lt;/code&gt;, &lt;code&gt;path&lt;/code&gt;, the field key&amp;rsquo;s &lt;code&gt;key&lt;/code&gt; name and &lt;code&gt;fingerprint&lt;/code&gt;, and &lt;code&gt;form&lt;/code&gt; (&lt;code&gt;ciphertext&lt;/code&gt;, or &lt;code&gt;plaintext&lt;/code&gt; once someone opened it with the key)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;auth&lt;/code&gt;, &lt;code&gt;auth_key_fingerprint&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;The authentication data parts, and the fingerprint of the one-time export key their sealed fields are sealed under&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;checksums&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;The SHA-256 of &lt;strong&gt;every&lt;/strong&gt; other file, as &lt;code&gt;sha256:&amp;lt;hex&amp;gt;&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="documents"&gt;Documents&lt;a class="hd-anchor" href="#documents" aria-hidden="true"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;One document per line, in the API representation: &lt;code&gt;id&lt;/code&gt;, the fields and &lt;code&gt;_meta&lt;/code&gt;, soft-deleted documents included. Typed values use MongoDB&amp;rsquo;s relaxed Extended JSON, so nothing is lost:&lt;/p&gt;</description></item><item><title>Encrypted fields format</title><link>https://fernandezvara.github.io/backd/docs/operate/administration/export-import/encrypted-format/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fernandezvara.github.io/backd/docs/operate/administration/export-import/encrypted-format/</guid><description>&lt;p&gt;This page is the &lt;strong&gt;specification&lt;/strong&gt; of field encryption&amp;rsquo;s storage format, version &lt;strong&gt;1&lt;/strong&gt;. It is complete enough to write a tool that reads an export package or a database dump with the field keys alone, with no &lt;code&gt;backd&lt;/code&gt; and no master key, and the test vectors at the end let that tool prove it. &lt;code&gt;backd&lt;/code&gt;&amp;rsquo;s own tests check the implementation against the same vectors, so this page and the code cannot drift apart without a test failing. How to &lt;em&gt;use&lt;/em&gt; encrypted fields is in &lt;a href="../../../../build/configuration/field-keys/"&gt;Field keys and encrypted fields&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Keeping packages safe</title><link>https://fernandezvara.github.io/backd/docs/operate/administration/export-import/keeping-packages-safe/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fernandezvara.github.io/backd/docs/operate/administration/export-import/keeping-packages-safe/</guid><description>&lt;p&gt;A package holds the data it was made from, and a key can open part of it. These notes are about where to keep them, how to give them to the commands and when to throw them away.&lt;/p&gt;
&lt;h2 id="the-package"&gt;The package&lt;a class="hd-anchor" href="#the-package" aria-hidden="true"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Treat it like the database it came from.&lt;/strong&gt; Even with ciphertext and anonymization it holds data. Keep it where only the people who may read the realm can, not in a shared folder, a ticket or a repository.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Permissions.&lt;/strong&gt; Files &lt;code&gt;backd&lt;/code&gt; writes are readable only by their owner (&lt;code&gt;0600&lt;/code&gt;, directories &lt;code&gt;0700&lt;/code&gt;), and &lt;code&gt;--archive&lt;/code&gt; makes a &lt;code&gt;.tar.gz&lt;/code&gt; with the same permissions. Keep them that way when you copy it; copy it over an encrypted channel (&lt;code&gt;scp&lt;/code&gt;, &lt;code&gt;rclone&lt;/code&gt; to a private bucket with encryption), not by email.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Verify before use.&lt;/strong&gt; An import checks every checksum before it trusts anything, so a package changed in transit or at rest is refused. That protects against damage, not against someone who can change the package (they can change the manifest and its checksums too) and not against reading it: get a package over a channel you trust.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Delete it when you are done.&lt;/strong&gt; A package is a copy of production that nobody backs up or audits. Remove the directory or archive (and any copy) as soon as the move or report is finished; the audit trail already says what was exported and when.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Authentication data is the most sensitive.&lt;/strong&gt; With &lt;code&gt;--include auth&lt;/code&gt; the package holds password hashes, which let anyone with the package guess passwords offline, plus the sealed second factors and push device tokens. Keep that package for as short a time as you can.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;An extract is still data.&lt;/strong&gt; A CSV or a &lt;code&gt;--fields&lt;/code&gt; package is a lossy view, but it can hold names and addresses: apply the same care, and use &lt;code&gt;--anonymize&lt;/code&gt; for anything that leaves the team.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="keys"&gt;Keys&lt;a class="hd-anchor" href="#keys" aria-hidden="true"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The one-time export key&lt;/strong&gt; opens the authenticator secrets, device tokens and Apple tokens of a package made with &lt;code&gt;--include auth&lt;/code&gt;. It is shown once and &lt;code&gt;backd&lt;/code&gt; keeps no copy; the manifest holds only its fingerprint. Store it &lt;strong&gt;apart from the package&lt;/strong&gt; (a password manager, a secrets store), never inside the same archive or the same ticket, and delete it with the package.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Raw keys in commands.&lt;/strong&gt; &lt;code&gt;key:&amp;lt;value&amp;gt;&lt;/code&gt; puts a key in your shell history and in the process list, where other users of the machine can read it. Prefer &lt;code&gt;env:&amp;lt;VAR&amp;gt;&lt;/code&gt;, which keeps it out of both (set it in the shell, not on the command line), or &lt;code&gt;file:&amp;lt;path&amp;gt;&lt;/code&gt; with permissions for your user only: a file readable by others draws a warning. The same applies to &lt;code&gt;--staging-password&lt;/code&gt;, &lt;code&gt;--mongo-uri&lt;/code&gt; (which holds credentials) and &lt;code&gt;--master-key&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;--auth-key-out&lt;/code&gt;&lt;/strong&gt; writes the key to a file readable only by you instead of printing it, so it never lands in a terminal&amp;rsquo;s scrollback or a CI log. Use it in scripts.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The master key&lt;/strong&gt; (&lt;code&gt;BACKD_SECRETS_KEY&lt;/code&gt;) never leaves an instance and is never in a package. A direct export needs it only for what the realm sealed; give it as &lt;code&gt;env:&lt;/code&gt; or &lt;code&gt;file:&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;In CI&lt;/strong&gt;, pass keys as masked secrets through environment variables, never on the command line, and make sure the job doesn&amp;rsquo;t store the package as an artifact.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="what-an-operator-can-do"&gt;What an operator can do&lt;a class="hd-anchor" href="#what-an-operator-can-do" aria-hidden="true"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Through the admin API, only a full administrator can export or import, with a fresh proof of identity for sessions, and every start and end is &lt;a href="../../audit/"&gt;audited&lt;/a&gt; with counts, never content. Authentication data is a separate, explicit choice audited as &lt;code&gt;export.auth&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;In &lt;a href="../direct-mode/"&gt;direct mode&lt;/a&gt; nobody is asked for a credential, because whoever holds MongoDB and &lt;code&gt;CONFIG_DIR&lt;/code&gt; already holds more than an admin account. The records are still written, as &lt;code&gt;cli:offline&lt;/code&gt;. Protect that access like the database itself.&lt;/li&gt;
&lt;li&gt;An anonymized export applies only the rules you declared; see &lt;a href="../seeding-staging/"&gt;Seeding staging&lt;/a&gt; before sharing a copy.&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>