Repository navigation
feat(providers): support credential-less provider creation for policy-only profiles #1978
Description
Problem Statement
Provider profiles can define endpoints and binaries without any credentials — the built-in pypi profile is a shipping example. However, openshell provider create requires at least one credential source, making it impossible to create a provider instance from a credential-less profile without the --credential NOOP= workaround.
This is inconvenient for downstream harnesses that use custom provider profiles purely for policy composition (network endpoint allow-lists contributed through provider attachment) without needing credential injection. The --credential NOOP= workaround exists but persists a dummy credential in the provider record, polluting credential state for a provider that has no credential semantics.
The gap exists at two layers:
- CLI (
crates/openshell-cli/src/main.rs:719): thecred_sourceclap arg group isrequired(true), soprovider createalways demands one of--credential,--from-existing, or--from-gcloud-adcat parse time. - Server (
crates/openshell-server/src/grpc/provider.rs:96-101):CreateProviderrejects empty credentials unlessprovider_type_allows_empty_credentials_for_refresh()returns true — but that function (crates/openshell-providers/src/profiles.rs:323-336) requires at least one gateway-mintable credential. A profile with zero credentials always returns false.
Proposed Design
Allow credential-less provider creation when the provider type's profile declares no required credentials.
CLI changes:
Make the cred_source arg group conditionally required. When no credential flag is provided, the CLI fetches the provider profile (it already does this for the refresh-bootstrap path at run.rs:4556-4559) and proceeds without credentials if the profile has no required credential entries. If the profile has required credentials and none were provided, the existing error is preserved.
Server changes:
Extend the CreateProvider validation (provider.rs:96-101) to also allow empty credentials when the profile exists and declares no required credentials. This can reuse the existing get_provider_type_profile lookup and add a check like:
fn profile_allows_no_credentials(profile: &ProviderTypeProfile) -> bool {
profile.credentials.iter().all(|c| !c.required)
}The existing allows_gateway_refresh_bootstrap path remains unchanged for its OAuth use case.
No changes needed to:
- Policy composition — already works with credential-less providers once they exist
- Provider attachment —
SandboxSpec.providersis name-based, credential-agnostic - Effective policy fetch —
profile_provider_policy_layersreads endpoints/binaries from the profile regardless of credentials
Alternatives Considered
Add a --no-credential CLI flag. This would work but adds a flag for what should be the default behavior when a profile has no credentials. The profile already declares what credentials it needs — the CLI should respect that.
Keep --credential NOOP= as the documented workaround. This persists a dummy credential in the provider record, which is confusing for operators inspecting provider state and may interact poorly with future credential driver backends (#1931).
Agent Investigation
- Confirmed
pypibuilt-in profile (providers/pypi.yaml) has nocredentialssection — only endpoints and binaries. - Confirmed CLI arg group
cred_sourceatcrates/openshell-cli/src/main.rs:719isrequired(true). - Confirmed server validation at
crates/openshell-server/src/grpc/provider.rs:96-101rejects empty credentials unlessallows_gateway_refresh_bootstrap()returns true. - Confirmed
allows_gateway_refresh_bootstrap()atcrates/openshell-providers/src/profiles.rs:323-336requires at least one gateway-mintable credential — zero-credential profiles always return false. - Confirmed the existing empty-credential test (
provider_create_allows_empty_credentials_for_gateway_refresh_profilesatcrates/openshell-cli/tests/provider_commands_integration.rs:1102) only covers the OAuth refresh bootstrap case, not the zero-credential profile case. - Searched open and closed issues — no existing issue covers this gap.
- Related: feat: add provider profile registry and policy layer composition foundation #947 (provider profile registry foundation), Enhanced Provider Management #896 (enhanced provider management umbrella).
Activity
johntmyers commentedon Jun 24, 2026
This will be addressed with #1988 so am closing this.
fix(sandbox): resolve OpenShell CLI compatibility issues
fix(sandbox): resolve OpenShell CLI compatibility issues
fix(sandbox): resolve OpenShell CLI compatibility issues
fix(sandbox): resolve OpenShell CLI compatibility issues
fix(sandbox): resolve OpenShell CLI compatibility issues
fix(sandbox): resolve OpenShell CLI compatibility issues
fix(sandbox): resolve OpenShell CLI compatibility issues
fix(sandbox): resolve OpenShell CLI compatibility issues
fix(sandbox): resolve OpenShell CLI compatibility issues
fix(sandbox): resolve OpenShell CLI compatibility issues
fix(sandbox): resolve OpenShell CLI compatibility issues
fix(sandbox): resolve OpenShell CLI compatibility issues
fix(sandbox): resolve OpenShell CLI compatibility issues
fix(sandbox): resolve OpenShell CLI compatibility issues
fix(fullsend-ai#1512)!: declare profile credentials for OpenShell 0.1
fix(#6966): declare the example's GitHub token the OpenShell 0.1 way
fix(#6966): declare the example's GitHub token the OpenShell 0.1 way