Skip to content

Conversation

@hsmatulis
Copy link

secrets: Add remote secrets providers

See the proposal here. This PR is currently a work in progress, demonstrating how user's would interact with the secrets management API

Which issue(s) does the PR fix:

Does this PR introduce a user-facing change?

[FEATURE] This introduces the "secret providers" core library for Prometheus, which will later enable fetching secrets from external systems. The config format will allow specifying a provider and its parameters to any `<secret>` fields.

Copy link
Member

@bwplotka bwplotka left a comment

Choose a reason for hiding this comment

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

This is good! Super minimal change surface.

I'd actually iterate over this PR and make this ready to be merged once common change is merged. We could double check all tests etc. 💪🏽

There are definitely some tests to fix, but it might be as trivial as adding (f *Field) Equals(other Field) bool so comparisons work correctly (they don't depend on state):

Image

},
func(error) {
logger.Info("Stopping scrape discovery manager...")
cancelScrape()
Copy link
Member

Choose a reason for hiding this comment

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

It probably needs its own context.

Comment on lines +657 to +661
var (
secretsManager *secrets.Manager
)
// needs logger: logger.With("component", "secrets manager")
secretsManager, err = secrets.NewManager(context.Background(), prometheus.DefaultRegisterer, secrets.Providers, cfgFile)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
var (
secretsManager *secrets.Manager
)
// needs logger: logger.With("component", "secrets manager")
secretsManager, err = secrets.NewManager(context.Background(), prometheus.DefaultRegisterer, secrets.Providers, cfgFile)
// TODO: Pass logger.With("component", "secrets manager")
secretsManager, err := secrets.NewManager(context.Background(), prometheus.DefaultRegisterer, secrets.Providers, cfgFile)

select {
case <-hup:
if err := reloadConfig(cfg.configFile, cfg.tsdb.EnableExemplarStorage, logger, noStepSubqueryInterval, callback, reloaders...); err != nil {
if err := reloadConfig(cfg.configFile, cfg.tsdb.EnableExemplarStorage, logger, noStepSubqueryInterval, secretsManager, callback, reloaders...); err != nil {
Copy link
Member

Choose a reason for hiding this comment

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

We could probably DRY this g.Add with something like

// before loop
reload = func()error { 
  return reloadConfig(cfg.configFile, cfg.tsdb.EnableExemplarStorage, logger, noStepSubqueryInterval, callback, reloaders...),
}
// ...
						if err := reload(); err != nil {

}
}

if err := secretsManager.HydrateConfig(nil, conf); err != nil {
Copy link
Member

Choose a reason for hiding this comment

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

Maybe we could work on this name. Reminds me to grab a cup of water though! (:

Image

Maybe:

Suggested change
if err := secretsManager.HydrateConfig(nil, conf); err != nil {
if err := secretsManager.ReloadConfig(context.TODO(), conf); err != nil {

NamespaceDiscovery NamespaceDiscovery `yaml:"namespaces,omitempty"`
Selectors []SelectorConfig `yaml:"selectors,omitempty"`
AttachMetadata AttachMetadataConfig `yaml:"attach_metadata,omitempty"`
ExampleSecret secrets.Field `yaml:"example_secret"`
Copy link
Member

Choose a reason for hiding this comment

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

Nice, easy use 👍🏽

Let's remove and iterate over this PR to be effectively testable and potentially mergable once common change is done, looks promising!

Copy link
Member

Choose a reason for hiding this comment

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

Although your other examples use *secrets.Field (pointer)?

@bwplotka
Copy link
Member

bwplotka commented Dec 8, 2025

For release log, keep in mind this is for user facing changes (e.g. user of Prometheus YAML). I would mention what user can expect (generic field and removal of ref).

I'd recommend:

[FEATURE] config: All secret fields e.g. `scrape[].basic_auth.password` supports now "generic" format.  This means users are able to specify in `password` either inlined secret as previously or one from certain provider. Currently only `inline` and `file` providers are supported, with more to come. Old `password_field`-like fields are still supported although discouraged. This change also removes the undocumented `password_ref`-like fields which were unused. See [documentation](TODO) and [PROM-47](https://github.com/prometheus/proposals/blob/main/proposals/0047-secret_providers.md) for details.

@bwplotka
Copy link
Member

Exciting feature! We even plan to mention it on KubeCon EU in March if that's ok (: cc @hsmatulis

Hopefully it's done until then 💪🏽

@bwplotka
Copy link
Member

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Generally enable reading secrets from files How to encrypt basic_auth password/password_file in prometheus.yml file?

2 participants