Summary
zopp principal export cannot be used on a principal created with --service — the export path requires a user identity (email/user_id), which principal create --service explicitly sets to None.
Where
apps/zopp-cli/src/commands/principal.rs, cmd_principal_create (around line 173): for is_service == true, (user_id, email) are set to (None, None).
apps/zopp-cli/src/commands/principal.rs, cmd_principal_export (around lines 563-573):
let email = principal.email.as_ref().ok_or("Cannot export service principal - no user identity")?;
let user_id = principal.user_id.as_ref().ok_or("Cannot export service principal - no user identity")?;
Impact
There's currently no way to provision a service/machine principal on one host and get its credential onto a second, separate host (a CI runner, an automated provisioning process, etc.) using the built-in create --service → export → import flow — export always fails with "Cannot export service principal - no user identity" for any principal created with --service.
This seems like a real gap for a CI/automation-focused secrets manager: the CI/CD guide (docs/docs/guides/ci-cd.md) recommends zopp principal create <name> --service -w <workspace> for automation identities, but the resulting credential's config (~/.zopp/config.json) has to be moved to the CI/automation host out-of-band (e.g. copied manually into a CI secret) — the same document's own workflow does exactly this ("The service principal's config is in ~/.zopp/config.json. Store it as a CI secret."), rather than using the export/import mechanism designed for multi-device credential transfer.
Question
Is this intentional (export/import is meant only for human multi-device onboarding, and service principals are meant to always be provisioned+exported from the machine that creates them, with the resulting config file transferred out-of-band)? If so, it might be worth a note in the docs (docs/docs/reference/cli/principal.md's export section, and/or the CI/CD guide) making that explicit, since the current docs don't distinguish this and it's easy to assume export/import works for service principals the same way it does for device principals.
If it's not intentional, happy to help however's useful — this came up while trying to build a "one host mints a scoped service-principal export for a second host to consume" provisioning flow.
Version
Found against main at e3aea52b9ec5a11c0da50cb49073ab5e1bf988df (2026-03-11), which is also the current main HEAD as of this report.
Summary
zopp principal exportcannot be used on a principal created with--service— the export path requires a user identity (email/user_id), whichprincipal create --serviceexplicitly sets toNone.Where
apps/zopp-cli/src/commands/principal.rs,cmd_principal_create(around line 173): foris_service == true,(user_id, email)are set to(None, None).apps/zopp-cli/src/commands/principal.rs,cmd_principal_export(around lines 563-573):Impact
There's currently no way to provision a service/machine principal on one host and get its credential onto a second, separate host (a CI runner, an automated provisioning process, etc.) using the built-in
create --service→export→importflow —exportalways fails with "Cannot export service principal - no user identity" for any principal created with--service.This seems like a real gap for a CI/automation-focused secrets manager: the CI/CD guide (
docs/docs/guides/ci-cd.md) recommendszopp principal create <name> --service -w <workspace>for automation identities, but the resulting credential's config (~/.zopp/config.json) has to be moved to the CI/automation host out-of-band (e.g. copied manually into a CI secret) — the same document's own workflow does exactly this ("The service principal's config is in~/.zopp/config.json. Store it as a CI secret."), rather than using the export/import mechanism designed for multi-device credential transfer.Question
Is this intentional (export/import is meant only for human multi-device onboarding, and service principals are meant to always be provisioned+exported from the machine that creates them, with the resulting config file transferred out-of-band)? If so, it might be worth a note in the docs (
docs/docs/reference/cli/principal.md'sexportsection, and/or the CI/CD guide) making that explicit, since the current docs don't distinguish this and it's easy to assume export/import works for service principals the same way it does for device principals.If it's not intentional, happy to help however's useful — this came up while trying to build a "one host mints a scoped service-principal export for a second host to consume" provisioning flow.
Version
Found against
mainate3aea52b9ec5a11c0da50cb49073ab5e1bf988df(2026-03-11), which is also the currentmainHEAD as of this report.