Skip to content

feat(issue-559): allow sensitive values to be passable as plaintext#610

Open
Breee wants to merge 1 commit intocrossplane:mainfrom
Breee:feat/issue-559
Open

feat(issue-559): allow sensitive values to be passable as plaintext#610
Breee wants to merge 1 commit intocrossplane:mainfrom
Breee:feat/issue-559

Conversation

@Breee
Copy link
Copy Markdown

@Breee Breee commented Mar 12, 2026

allow sensitive values to be passable as plaintext

Draft for #559 to have a base for discussion. This shall give you an idea of the requirement i have.
This was the easiest implementation approach I found that is fully backwards compatible.
However, it does add some complexity to the builder logic and generated code, so I'm open to suggestions on how to make it cleaner or if we want to take a different approach.
In general i need some more flexibility with what i can pass in as secret and what i can pass in as plaintext for the provider-keycloak, as OIDC / SAML clients and tools vary alot in what they support and need.

Problem

Sensitive fields currently only support secret references. Users must create a Kubernetes Secret even if they just want to pass a value directly. This is inflexible and doesn't match how the underlying Terraform providers work (which accept plaintext).

Potential Solution

I Added a AllowPlaintextValue config flag. When enabled, generates both the regular field AND the secret reference field for sensitive parameters. Users pick which one to use via OR validation (provide one or the other, not both).

Runtime checks the plaintext field first, falls back to secret reference if not set. Its Backwards compatible so existing secret-only resources work unchanged.

Usage

Provider configuration:

p.AddResourceConfigurator("keycloak_oidc_identity_provider", func(r *config.Resource) {
    r.ShortGroup = "oidc"
    
    // Mark fields as sensitive in Terraform schema
    if s, ok := r.TerraformResource.Schema["client_id"]; ok {
        s.Sensitive = true
    }
    if s, ok := r.TerraformResource.Schema["client_secret"]; ok {
        s.Sensitive = true
    }
    
    // Enable plaintext AND secret reference support
    r.Sensitive.AllowPlaintextValue = true
})

See https://github.com/crossplane-contrib/provider-keycloak/blob/feat/upjet-test/config/oidc/config.go#L30

Generated CRD types will then look like this:

type IdentityProviderParameters struct {
    // [...more stuff...]
    // Plaintext field (new!)
    ClientID *string `json:"clientId,omitempty"`
    
    // Secret reference field (existing)
    ClientIDSecretRef v1.SecretKeySelector `json:"clientIdSecretRef,omitempty"`
    
    ClientSecret *string `json:"clientSecret,omitempty"`
    ClientSecretSecretRef *v1.SecretKeySelector `json:"clientSecretSecretRef,omitempty"`
   // [...more stuff...]
}

see https://github.com/crossplane-contrib/provider-keycloak/blob/feat/upjet-test/apis/cluster/oidc/v1alpha1/zz_identityprovider_types.go#L43

Example

After enabling AllowPlaintextValue, users can choose:

# Option 1: Plaintext (new)
spec:
  forProvider:
    clientId: "my-client-id"
    clientSecret: "my-secret"

# Option 2: Secret references 
spec:
  forProvider:
    clientIdSecretRef:
      name: my-secret
      key: client_id
    clientSecretSecretRef:
      name: my-secret
      key: client_secret
      [... other fields ...]

Testing

I Tested in provider-keycloak with both plaintext and secret reference patterns.
Both resources successfully created and synced in a dev cluster.

@Breee Breee marked this pull request as ready for review March 12, 2026 16:25
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 12, 2026

📝 Walkthrough

Walkthrough

This change introduces support for plaintext values in sensitive fields. A new AllowPlaintextValue flag enables sensitive fields to be handled as plaintext alongside secret references, with corresponding adjustments to field generation, validation logic, and runtime processing across the configuration and builder layers.

Changes

Cohort / File(s) Summary
Configuration & Type Definitions
pkg/config/resource.go, pkg/types/field.go
Added AllowPlaintextValue field to Sensitive struct and AlternateFieldName field to Field struct. When plaintext is allowed, the secret reference field is marked optional and a schema copy enables plaintext field usage.
Builder & Validation Logic
pkg/types/builder.go
Extended validation rule generation to support alternate field paths. Generates OR conditions requiring either the primary or alternate field when AllowPlaintextValue is enabled. Added newTopLevelRequiredParamWithAlternate constructor to track alternate fields alongside primary fields in required parameter collection.
Resource Processing
pkg/resource/sensitive.go
Added pre-check in GetSensitiveParameters to skip secret reference processing when a plaintext value already exists in the Terraform state.

Sequence Diagram(s)

sequenceDiagram
    participant Config as Configuration
    participant FieldGen as Field Generator
    participant Validator as Validation Builder
    participant Processor as Resource Processor
    participant TFState as Terraform State

    Config->>FieldGen: AllowPlaintextValue = true
    FieldGen->>FieldGen: Create regular field<br/>(AlternateFieldName set)
    FieldGen->>FieldGen: Mark secret ref optional
    FieldGen->>Validator: Field with AlternateFieldName
    Validator->>Validator: Generate OR validation:<br/>primaryField OR alternateField
    Validator->>Validator: Track alternate path in<br/>topLevelRequiredParam
    
    Processor->>TFState: GetValue(tfPath)
    alt Plaintext value exists
        Processor->>Processor: Skip secret ref processing
    else No plaintext value
        Processor->>Processor: Process secret reference
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description check ✅ Passed The description is thorough and directly relates to the changeset, explaining the problem, solution, usage, and testing.
Configuration Api Breaking Changes ✅ Passed Adding a new optional field to an exported struct is backward compatible and does not constitute a breaking change to the Configuration API.
Generated Code Manual Edits ✅ Passed The pull request does not modify any files matching the 'zz_*.go' pattern. All changes are made to legitimate source files in appropriate directories.
Template Breaking Changes ✅ Passed No changes to pkg/controller/external*.go template files detected in this pull request; modifications are limited to configuration and code generation logic.
Title check ✅ Passed The title clearly and descriptively summarizes the main change: enabling sensitive values to be passed as plaintext, which aligns perfectly with the PR objectives and file changes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

CodeRabbit can generate a title for your PR based on the changes.

Add @coderabbitai placeholder anywhere in the title of your PR and CodeRabbit will replace it with a title based on the changes in the PR. You can change the placeholder by changing the reviews.auto_title_placeholder setting.

@Breee Breee changed the title feat(issue-559): allow sensitive values to be passable as plaintext as well feat(issue-559): allow sensitive values to be passable as plaintext Mar 13, 2026
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.

1 participant