Export users from Ory Kratos
Ce contenu n’est pas encore disponible dans votre langue.
This guide walks through exporting the identities of a self-hosted Ory Kratos instance into the Canonical Migration Format (CMF), checking what came out, and preparing the result for import into another provider.
How iamigrate exports from Kratos
Section titled “How iamigrate exports from Kratos”iamigrate export --source kratos reads every identity through the Admin API (GET /admin/identities), 250 per page, following Kratos’ pagination links until the last page. It requests each identity’s password credential, so password hashes are exported and users can keep their password on the target.
Each identity becomes one CMF user. Identities that can’t be translated are skipped and listed in manifest.json instead of failing the export.
Prerequisites
Section titled “Prerequisites”- iamigrate installed (see Installation).
- Network access to the instance’s Admin API, usually on port
4434.
The export contains password hashes and personal data. Write it somewhere access-controlled, and delete it once the migration is done.
1. Run the export
Section titled “1. Run the export”export KRATOS_ADMIN_URL=http://127.0.0.1:4434
iamigrate export --source kratos --out ./export/exported 1250 users -> export/users.cmf.jsonl.gz (3 skipped)You can pass --admin-url instead of setting $KRATOS_ADMIN_URL. The command writes:
export/├── users.cmf.jsonl.gz # one CMF user per exported identity├── manifest.json # counts per hash algorithm, plus skipped identities└── mapping.yaml # scaffolded mapping, with no target set yetThe export is a snapshot. Identities created, and passwords changed, after it runs aren’t in it, so plan a freeze or a final re-export before cutover.
2. Review the manifest
Section titled “2. Review the manifest”cat export/manifest.json{ "record_count": 1250, "hash_algorithm_counts": { "argon2": 120, "bcrypt": 1130 }, "skipped_records": [ { "source_id": "140625ed-95b8-41b3-8882-c3adee5833f8", "reason": "missing hashed_password on identity's password credential" } ]}hash_algorithm_countstells you which algorithms the target must accept. Kratos storesbcryptorargon2(argon2id) hashes, depending on itshashersconfig.skipped_recordslists identities that aren’t inusers.cmf.jsonl.gz, by Kratos identity ID.
| Skip reason | Cause |
|---|---|
missing hashed_password on identity's password credential | The identity has no password hash, for example because it was created through the Admin API without one |
unrecognized password hash format: ... | The stored hash isn’t a format iamigrate recognizes |
Skipped identities aren’t migrated at all. If you need them on the target, recreate them there and have them set a password, or sign in with the same method they used on Kratos.
3. Understand what’s exported
Section titled “3. Understand what’s exported”Exported
Section titled “Exported”| Kratos field | CMF field |
|---|---|
id | source_id |
traits.email | emails[0], marked primary. Verified if a matching verifiable_addresses entry is verified. |
traits.username | username |
state: inactive | blocked: true |
metadata_admin | app_metadata |
metadata_public | user_metadata |
credentials.password.config.hashed_password | password, with the algorithm and parameters detected from the hash |
The Kratos identity UUID becomes source_id, and is what import reports refer to. Some targets reuse it as the user ID; for example, Auth0 turns it into auth0|<uuid>.
Not exported
Section titled “Not exported”- Other traits. Only
emailandusernameare read. Names, phone numbers, and any custom traits are dropped, soprofileis empty on every exported user. - MFA. TOTP, recovery codes (
lookup_secret), and WebAuthn credentials aren’t exported. Users have to set up a second factor again on the target. - Social sign-in links (
oidccredentials). - Recovery addresses and timestamps such as creation date.
If you need any of these, fetch them from the Admin API yourself and merge them into the CMF records, for example adding names to profile with jq, before you import.
4. Prepare for import
Section titled “4. Prepare for import”mapping.yaml is scaffolded with target: "". Set the target before you validate with it:
iamigrate map --target <target> --mapping ./export/mapping.yamlThen check the export against the target’s capabilities. No network calls are made:
iamigrate validate --in ./export/users.cmf.jsonl.gz --mapping ./export/mapping.yaml --target <target>From there, follow the import guide for your target:
- Import users into Auth0
- Import users into Ory Kratos, for example to move between Kratos instances
Rehearse with test data
Section titled “Rehearse with test data”To try the export without a real instance, import a fixture into a disposable Kratos (see Import users into Ory Kratos), then export it back:
iamigrate testdata generate --count 50 --hash bcrypt:cost=10 --hash argon2 --out ./fixtures/iamigrate import kratos --in ./fixtures/users.cmf.jsonl.gziamigrate export --source kratos --out ./export/Every fixture user comes back with the same email and password hash, but with a Kratos UUID as source_id and an empty profile. That’s the data loss described in Step 3.