Skip to content

Support configurable credential placeholder shapes - #143

Merged
xai merged 2 commits into
mainfrom
feat/auth-token-placeholders
Oct 9, 2026
Merged

xai merged 2 commits into
mainfrom
feat/auth-token-placeholders

Conversation

@xai

@xai xai commented Oct 6, 2026 •

Copy link
Copy Markdown
Collaborator

What it does

Adds optional credentials.sources.<id>.placeholder settings for tools and features: prefix, suffix, random-body encoding and length. This lets extensions accommodate client-side token format checks without exposing the real secret. Existing defaults and gateway release restrictions remain unchanged. Invalid shapes are rejected; generation failures abort startup instead of injecting the real credential.

Fixes #142.

Addresses the generic compatibility problem reported in #128, without adding that tool.

How to test

  1. Run make build && make test && make lint.
  2. In a local extension with an env credential and network.serviceAuth, add this under its credential source:
    placeholder:
      prefix: "vendor_"
      suffix: "_end"
      random: { encoding: hex, length: 32 }
  3. Supply a dummy credential through the usual secrets file and start ./bin/enclave --tool <tool> shell with the gateway enabled. Inspect that credential's env var: expect vendor_, 32 lowercase hex characters, and _end, not the dummy value. A fresh session should get a different value.
  4. Change length to 1: startup should reject the configuration. Remove placeholder: expect the original ENCLAVE_SECRET_ format again. Restore the local extension afterward.

The gateway tests cover replacement of custom placeholders and denial on HTTP or unauthorized hosts. The dummy credential check does not test upstream authentication.

Follow-ups

Rebase #128 after this lands and configure its credential shape there.

Breaking changes

  • This PR introduces breaking changes and has been coordinated with maintainers.

Review checklist

@xai xai added the enhancement New feature or request label Oct 6, 2026
@xai

xai commented Oct 6, 2026 •

Copy link
Copy Markdown
Collaborator Author

@EclipseSourceAI

@EclipseSourceAI EclipseSourceAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

Autonomous AI review.

This review was done by an AI agent and therefore may contain mistakes. Feel free to ignore any comment you disagree with. A thumbs-down reaction on a comment marks it as rejected for follow-up reviews. Noting why in a reply helps, since replies are read too.

Resolving all AI comments does not lead to an automatic approval. A maintainer still needs to review and sign off on the overall architecture and design.

To get an updated review after pushing changes, a maintainer may re-request a review from this account.

Running in Eclipse Enclave, submitted via review-guard-mcp

Adds an optional credentials.sources.<id>.placeholder (prefix, suffix, random hex/base64url/alphanumeric body with per-encoding minimum lengths of at least 128 bits) to tool and feature specs. The shape is validated at load, passed through activeSecret to the placeholder resolver, and used instead of the default ENCLAVE_SECRET_<hex> value. The gateway needs no changes because it already matches the full registered placeholder with strings.Contains. The PR also changes placeholder generation failures from "warn and inject the real value" to "abort startup", and renames the resolver's cache key to secret ID, which is what callers already passed.

Build, the tests for the touched packages, and golangci-lint all pass locally on the merged tree.

Points for maintainers:

  • Silent no-op config: a placeholder on a credential with no serviceAuth entry is accepted and ignored, so the raw value is injected. This should fail at load like the other serviceAuth mapping checks.
  • Spec/model coupling: the spec struct embeds model.SecretPlaceholderConfig directly instead of using a spec* type mapped in buildSecrets.
  • Fail-closed change: with load-time validation, generation can now only fail if crypto/rand fails. The change is sound, but it does change behavior for the default placeholder path too.
  • The remaining comments are smaller cleanups: a validator named Alphabet(), an inline normalize block that shadows copy, a dead else, import grouping, and field ordering.

Comment thread internal/config/spec_map.go Outdated
Comment thread internal/config/spec.go Outdated
Comment thread internal/config/secrets.go Outdated
Comment thread internal/model/secret_placeholder.go Outdated
Comment thread internal/runtime/auth_manager.go Outdated
Comment thread internal/auth/secret_injection_test.go Outdated
Comment thread internal/model/types.go Outdated
@xai
xai requested a review from EclipseSourceAI October 6, 2026 17:10

@EclipseSourceAI EclipseSourceAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

Autonomous AI review.

This review was done by an AI agent and therefore may contain mistakes. Feel free to ignore any comment you disagree with. A thumbs-down reaction on a comment marks it as rejected for follow-up reviews. Noting why in a reply helps, since replies are read too.

Resolving all AI comments does not lead to an automatic approval. A maintainer still needs to review and sign off on the overall architecture and design.

To get an updated review after pushing changes, a maintainer may re-request a review from this account.

Running in Eclipse Enclave, submitted via review-guard-mcp

Only one commit landed since my last review (adf9300). It addresses all seven points I raised: the silent no-op (placeholder without network.serviceAuth) now fails at spec load, with a new test covering sandbox/mixin and several network shapes; the spec schema now has its own specCredentialPlaceholder/specCredentialPlaceholderRandom mapped in buildSecrets instead of embedding the model type; the Alphabet()/copy shadowing issue is gone via ValidatedAlphabet() and a normalizeSecretPlaceholder helper matching the existing normalize pattern; the dead else in auth_manager.go is flattened; the import grouping nit is fixed; and Placeholder was moved to the end of SecretConfig, specCredentialSource, and activeSecret to keep the diff minimal.

Build, go build ./..., and tests for the touched packages (config, model, auth, runtime) pass on the merged tree. No new issues found in the fix-up commit, nothing further to flag inline.

These previous comments can be resolved as they are now handled:

I can't resolve them myself as I would need write permission on this repository.

@xai
xai marked this pull request as ready for review October 6, 2026 17:18
@tortmayr
tortmayr self-requested a review October 6, 2026 19:44

@tortmayr tortmayr left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks good to me and everything works as expected during testing.

One thing i noticed, which we should probably handle in a follow-up:

If a feature is enabled explicitly via -- features and it fails do load e.g because the secret format does not match it is just skipped with a warning.
IMO explicitly enabled features should probably hard error instead of a warning and silent skip

@xai
xai merged commit 407eada into main Oct 9, 2026
9 checks passed
@xai
xai deleted the feat/auth-token-placeholders branch October 9, 2026 10:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Handle clients that reject secret placeholders based on token format

3 participants