Skip to content

principal export fails for --service principals (requires email/user_id, which create --service leaves unset) #88

Description

@br0kend

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions