There is no workflow in bc-envelope-cli to convert a XID document with private keys and provenance mark generator into a publicly distributable version while preserving signatures.
To create a publicly distributable XID document, users need to:
- Elide or omit private keys - Replace private key assertions with ELIDED placeholders (preserving digest tree) or remove them entirely
- Elide the provenance mark generator - The generator allows creating new provenance marks and should be elided (not omitted) to preserve the digest tree
- Preserve the signature - If signed, the signature should remain valid after elision
- OR re-sign - If modifications break the signature, the document needs re-signing
These commands hard-code PrivateOptions::Include and don't support controlling output:
| Command | Missing Options |
|---|---|
xid method add |
--private, --generator |
xid method remove |
--private, --generator |
xid delegate add |
--private, --generator |
xid delegate update |
--private, --generator |
xid delegate remove |
--private, --generator |
xid service add |
--private, --generator |
xid service update |
--private, --generator |
xid service remove |
--private, --generator |
xid attachment add |
--private, --generator |
xid attachment remove |
--private, --generator |
xid provenance next |
--private, --generator |
These commands have --private but not --generator:
| Command | Missing Options |
|---|---|
xid key add |
--generator |
xid key update |
--generator |
xid key remove |
--generator |
The GeneratorOptions::Elide variant exists and is listed in help text, but is explicitly rejected at runtime in xid new with:
"Elide is not allowed for 'xid new'. Use 'omit' (the default)..."
This is correct for xid new (can't elide what doesn't exist), but elide should be available for commands that operate on existing documents.
No command exists to simply re-output an existing XID document with different private/generator options without modifying it.
Goal: Create reusable argument structs that can be composed into commands needing output control.
/// Options controlling how sensitive data is output in XID documents.
#[derive(Debug, Args, Default)]
pub struct OutputOptions {
#[command(flatten)]
pub private_opts: PrivateOutputArgs,
#[command(flatten)]
pub generator_opts: GeneratorOutputArgs,
}
#[derive(Debug, Args, Default)]
pub struct PrivateOutputArgs {
/// Whether to include, omit, elide, or encrypt private keys.
#[arg(long = "private", default_value = "include")]
pub private: PrivateOptions,
}
#[derive(Debug, Args, Default)]
pub struct GeneratorOutputArgs {
/// Whether to include, omit, elide, or encrypt the provenance mark generator.
#[arg(long = "generator", default_value = "include")]
pub generator: GeneratorOptions,
}Update to accept OutputOptions instead of individual PrivateOptions and Option<GeneratorOptions>:
pub fn xid_document_to_ur_string(
xid_document: &XIDDocument,
output_opts: &OutputOptions,
password_args: Option<&WritePasswordArgs>,
shared_password: Option<String>,
signing_options: XIDSigningOptions,
) -> Result<String>pub trait HasOutputOptions {
fn output_options(&self) -> &OutputOptions;
}Goal: Add --generator option to existing key commands.
- Add
GeneratorOutputArgstoCommandArgs - Pass generator option to
xid_document_to_ur_string
- Add
GeneratorOutputArgstoCommandArgs - Pass generator option to
xid_document_to_ur_string
- Add
GeneratorOutputArgstoCommandArgs - Pass generator option to
xid_document_to_ur_string
Goal: Add both --private and --generator options to all XID-modifying commands.
xid method add- AddOutputOptionsxid method remove- AddOutputOptions
xid delegate add- AddOutputOptionsxid delegate update- AddOutputOptionsxid delegate remove- AddOutputOptions
xid service add- AddOutputOptionsxid service update- AddOutputOptionsxid service remove- AddOutputOptions
xid attachment add- AddOutputOptionsxid attachment remove- AddOutputOptions
xid provenance next- AddOutputOptions
Goal: Create a command to re-output an existing XID document with different output options without modifying it.
/// Export a XID document with specified output options.
///
/// This command reads an existing XID document and outputs it with
/// the specified handling of private keys and provenance generator.
/// Use this to create publicly distributable versions of XID documents.
#[derive(Debug, Args)]
#[group(skip)]
pub struct CommandArgs {
#[command(flatten)]
output_opts: OutputOptions,
#[command(flatten)]
password_args: ReadWritePasswordArgs,
#[command(flatten)]
verify_args: VerifyArgs,
#[command(flatten)]
signing_args: SigningArgs,
#[command(flatten)]
envelope_args: EnvelopeArgs,
}Add Export(export::CommandArgs) to SubCommands enum.
# Create publicly distributable version (elide secrets, preserve signature)
envelope xid export --private elide --generator elide $FULL_XID
# Create minimal version (omit secrets, re-sign required)
envelope xid export --private omit --generator omit --sign inception $FULL_XID
# Encrypt secrets for storage, re-sign
envelope xid export --private encrypt --generator encrypt \
--encrypt-password "secret" --sign inception $FULL_XID- Test
--private elidepreserves signature - Test
--generator elidepreserves signature - Test
--private omitrequires re-signing - Test
--generator omitrequires re-signing - Test all combinations work correctly
- Test export with elision preserves signature
- Test export with omission invalidates signature
- Test export with encryption
- Test round-trip: create → export public → verify signature
- Add section on creating publicly distributable XID documents
- Document
xid exportcommand - Add workflow examples for common use cases
Ensure all new options have clear /// doc comments that appear in --help.
- Phase 1 - DRY infrastructure (blocks all other phases)
- Phase 2 - Key commands (small scope, validates Phase 1 design)
- Phase 3 - Non-key commands (apply pattern from Phase 2)
- Phase 4 - Export command (uses all infrastructure from prior phases)
- Phase 5 - Tests (validates all functionality)
- Phase 6 - Documentation (documents completed features)
- All XID-modifying commands support
--privateand--generatoroptions -
xid exportcommand exists and works correctly - Elision preserves existing signatures
- Omission correctly requires re-signing
- No code duplication for output option handling
- Tests cover all new functionality
- Documentation is complete and accurate