Skip to content

credential-templates: provider is unvalidated, so provider="ibmcloud" silently injects no credentials #191

Description

@jgruberf5

POST /api/credential-templates accepts any string as provider, stores it, and returns 200. Only two values are ever matched when credentials are resolved, so anything else creates a template that looks correct everywhere in the API and silently injects nothing.

Observed on v4.0.0-rc1 (ghcr.io/f5devcentral), container engine.

What I did

Provisioning a fresh instance, I created the IBM template the obvious way:

POST /api/credential-templates
{"name":"IBM ROKs Testing","provider":"ibmcloud","region":"us-east",
 "ibmcloud_api_key":"","ibmcloud_resource_group":"default"}

201, and it reads back looking entirely healthy:

id=2 name=IBM ROKs Testing provider=ibmcloud region=us-east
     ibmcloud_resource_group=default has_ibmcloud_api_key=true

The project shows credential_template_id: 2. Nothing anywhere says it is wrong.

What happens

Credential resolution branches on two literals (credentials_service.py:190,253):

if template.provider == 'aws':  ...
if template.provider == 'ibm':  ...

"ibmcloud" matches neither, so resolution falls off the end and lands on the global fallback. The worker log is the only place the problem is visible, and even there it reads like information rather than an error:

Using credential template 'IBM ROKs Testing' for project f5e2e-v1-new-connected
Using global credentials from environment (.env) for project f5e2e-v1-new-connected

There is no IBM key in the deployment's .env, so IBMCLOUD_API_KEY is never injected. Every module then runs without it.

How it actually surfaces

Nowhere near the cause. A container module reports:

✓ Applied 9 field(s) from environment: prefix, ibmcloud.region, ibmcloud.resource_group,
  cluster.openshift_version, cluster.vpc_cidr, cluster.create, cluster.workers_per_zone,
  cluster.public_gateway, resources.transit_gateway.existing
step 'cluster-up' failed (exit 1)

Nine fields where there should be ten — the missing one is the API key, and you only notice by counting. An opentofu module fails as a Terraform provider error:

Resource Manager service: "The BearerToken property is required but was not specified."

Neither message mentions credentials, templates, or providers. I spent a while checking project bindings, module variables, platform_provider, and a PUT of the key onto the module — all dead ends — before reading the resolver.

Setting provider to ibm fixed it immediately: the global-fallback line disappears and the key reaches the container.

Why ibmcloud is the natural thing to write

Every adjacent field on the same object is spelled that way — ibmcloud_api_key, ibmcloud_resource_group, has_ibmcloud_api_key, ibm_cos_instance_name. provider: "ibm" is the odd one out, and nothing at the API layer hints at it.

Suggested fix

Validate provider against the values resolution actually handles — a Literal["aws","ibm",…] on the create/update model, so a wrong value is a 422 at the point of the mistake rather than a Terraform error hours later:

{"detail":[{"loc":["body","provider"],"msg":"must be one of: aws, ibm, gcp, azure"}]}

Accepting "ibmcloud" as an alias for "ibm" would also be defensible given the field naming, but rejecting it is better than storing it.

Worth considering as a second guard: when a project has a credential template whose provider yields no credentials, log that at WARNING rather than falling through to the global path at INFO. "Template found, contributed nothing, falling back" is the sentence that would have saved the investigation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    backendFastAPI backend: routes, services, tasksbugSomething is broken or behaves incorrectlycredentialsCloud/SSH/git credentials and secrets

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions