Skip to content

config: render the Okta private key as a multiline field - #214

Merged
haroonkhan-c1 merged 4 commits into
mainfrom
haroon.khan/multiline-secret-config-fields
Sep 18, 2026
Merged

haroonkhan-c1 merged 4 commits into
mainfrom
haroon.khan/multiline-secret-config-fields

Conversation

@haroonkhan-c1

@haroonkhan-c1 haroonkhan-c1 commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Summary

  • okta-private-key holds a PEM-encoded key, but ConductorOne's connector config UI rendered it as a single-line masked input, so the value had to be pasted into a one-line box and couldn't be read back sensibly. Declaring it with field.MultilineField makes the UI render a masked textarea instead.
  • One-line change in pkg/config/config.go. WithIsSecret is retained — multiline is its own StringFieldType rather than a modifier, but is_secret lives on Field, so the two still compose and the value stays sealed and write-only server side.
  • pkg/config/conf.gen.go is deliberately unchanged. MultilineField leaves the field's type as plain text, so OktaPrivateKey stays a Go string and nothing in pkg/connector or pkg/oktaauth needs to change. (Modelled as a file-upload field instead, the generated type would have become []byte and both would have needed updating.)

Requires field.MultilineField from ConductorOne/baton-sdk#1139, released in v0.31.0. That has landed — main is already on v0.31.0 via baton-admin, and this branch is rebased on top, so no go.mod change is needed here and nothing blocks merge.

Test plan

  • go build ./... against the real released v0.31.0 (no local replace)
  • go generate ./... leaves pkg/config/conf.gen.go unchanged; OktaPrivateKey is still string
  • go test ./... passes (pkg/connector, pkg/oktaauth)
  • baton-okta config emits "type": "STRING_FIELD_TYPE_MULTILINE" on okta-private-key with "isSecret": true preserved, and api-token unaffected
  • Rendered in the ConductorOne config UI: masked textarea, reveal toggle masks/unmasks, a 4-line PEM wraps without horizontal scroll. Verified against the equivalent schema; the C1-side rendering path is unchanged by the enum rework.
  • config_schema.json regenerated by the metadata workflow picks up the new field type

🤖 Generated with Claude Code

Comment thread pkg/config/config.go Outdated
@github-actions

github-actions Bot commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Connector PR Review: config: render the Okta private key as a multiline field

Blocking Issues: 0 | Suggestions: 0 | Threads Resolved: 0
Criteria: Criteria status: loaded .claude/skills/ci-review.md from trusted base 2b4ae7ef95ce.
Review mode: incremental since 1eda9f8f
View review run

Review Summary

The full PR diff was scanned for security and correctness: pkg/config/config.go switches okta-private-key from StringField to MultilineField, with the matching config_schema.json regeneration and doc rewording. Both prior blocking findings are addressed — field.MultilineField does exist in the now-pinned baton-sdk v0.31.0 (pkg/field/fields.go:273, same StringVariant, so conf.gen.go correctly stays OktaPrivateKey string), and the new commit ec5cffe removes the customer-facing "C1 release that predates that support" framing from both docs/connector.mdx:399 and the OAuth step at :470, resolving the earlier docs-contradiction suggestion. WithIsSecret(true) is preserved in the generated schema, the field name and variant are unchanged so this is not a breaking change, and the docs' claim that literal \n is expanded before parsing matches pkg/oktaauth/oktaauth.go:122. No new issues found.

Security Issues

None found.

Correctness Issues

None found.

Suggestions

None.

@github-actions github-actions Bot 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.

Blocking issues found — see review comments.

Comment thread pkg/config/config.go

@github-actions github-actions Bot 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.

Blocking issues found — see review comments.

okta-private-key holds a PEM-encoded key, but ConductorOne's connector config
UI rendered it as a single-line masked input, so the value had to be pasted
into a one-line box and could not be read back sensibly. Declaring it with
field.MultilineField makes the UI render a masked textarea instead.

WithIsSecret is retained: multiline is its own StringFieldType rather than a
modifier, but is_secret lives on Field, so the two still compose and the value
stays sealed and write-only server side.

pkg/config/conf.gen.go is deliberately unchanged. MultilineField leaves the
field's type as plain text, so OktaPrivateKey stays a Go string and nothing in
pkg/connector or pkg/oktaauth needs to change. (Modelled as a file-upload field
instead, the generated type would have become []byte and both would have needed
updating.)

Requires baton-sdk v0.31.0 for field.MultilineField, which main already pins.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@haroonkhan-c1
haroonkhan-c1 force-pushed the haroon.khan/multiline-secret-config-fields branch from c1bb0e3 to db7a48f Compare September 18, 2026 18:49

@github-actions github-actions Bot 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.

Blocking issues found — see review comments.

config_schema.json picks up "type": "STRING_FIELD_TYPE_MULTILINE" on
okta-private-key from the field declaration change. baton_capabilities.json is
unchanged -- this is a config render hint, not a capability.

docs/connector.mdx previously documented a workaround for the single-line form:
collapse the PEM onto one line with literal \n escapes, or the connector fails
with "no PEM block found". That workaround is what this change removes, so the
note now leads with pasting the PEM directly.

It deliberately does not claim the text area is live everywhere. The connector
only advertises the field type; whether it renders as a text area depends on the
C1 release, and a C1 that predates that support falls back to a single-line
input. So the escaped single-line instructions are kept for that case, with an
explicit note that the escaped form continues to work either way --
parseRSAPrivateKey still expands a literal \n before parsing -- so nobody who
entered a key the old way has to migrate.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Comment thread docs/connector.mdx

@github-actions github-actions Bot 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.

No blocking issues found.

…field

The "Private key format" note was updated to lead with pasting the PEM
directly, but two other places still asserted the opposite and contradicted it:

- docs/connector.mdx, the OAuth credential step, told you to enter the key "on
  a single line, with each line break written as \n" with no mention that
  pasting works where the field renders as a text area.
- README.md said the form field "holds a single line" and that a pasted
  multi-line PEM "fails with no PEM block found", flatly.

Both now match the note's framing: the connector declares the field multiline,
so the PEM goes in as-is where C1 renders a text area, with the escaped
single-line form documented for C1 releases that predate that support and
called out as still working either way.

Kept conditional rather than asserting the text area everywhere, because the
connector only advertises the field type -- whether it renders as one depends
on the C1 release, and that support is not out yet.

docs/docs-info.md needs no change: its \n-normalization note describes
parseRSAPrivateKey's behavior, which is unchanged and is what keeps the escaped
form valid.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@github-actions github-actions Bot 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.

No blocking issues found.

Copilot AI 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.

🟢 Approval recommended

The change is narrowly scoped to config schema rendering, preserves secret handling, and the documentation/schema updates align with the new field type.

Pull request overview

Updates the connector configuration schema so the Okta private key (a PEM block) is collected as a multiline secret in ConductorOne’s connector config UI, avoiding single-line paste/escape issues while keeping the value write-only.

Changes:

  • Switch okta-private-key from field.StringField to field.MultilineField while retaining WithIsSecret(true).
  • Refresh documentation to explain multiline UI behavior and the fallback \n-escaped format for older C1 releases.
  • Update config_schema.json to emit STRING_FIELD_TYPE_MULTILINE for okta-private-key.
File summaries
File Description
README.md Clarifies how to enter PEM keys in the C1 form (multiline where supported, \n fallback).
pkg/config/config.go Declares okta-private-key as a multiline schema field while keeping it secret.
docs/connector.mdx Updates setup instructions to reflect multiline key entry and compatibility guidance.
config_schema.json Adds the multiline string field type for okta-private-key in the exported schema.
Review details
  • Files reviewed: 4/4 changed files
  • Comments generated: 0
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Copilot AI 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.

🟢 Approval recommended

The field type, secret flag, generated schema, SDK version, and documentation are consistent.

Review details
  • Files reviewed: 4/4 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

Copilot AI 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.

Copilot review overview

🟢 Approval recommended

The implementation, generated schema, secret handling, and documentation are consistent.

Review effort: Balanced
Findings: None

@haroonkhan-c1
haroonkhan-c1 dismissed github-actions[bot]’s stale review September 18, 2026 21:59

baton-sdk version 0.31.0 has landed. This is a stale review.

Comment thread docs/connector.mdx Outdated
**Private key format.** The connector declares **Okta Private Key** as a multiline field, so where the C1 connector form renders it as a text area you can paste the PEM in directly, line breaks and all.

Enter the key on one line, writing each line break as a literal `\n`:
On a C1 release that predates that support the field is still a single-line input. Pasting a multi-line PEM into it replaces the line breaks with spaces, and the connector rejects the result with `oktaauth: parse private key: no PEM block found`. Enter the key on one line instead, writing each line break as a literal `\n`:

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.

nit: connector.mdx gets turned into documentation on the c1 website, i.e. https://www.c1.ai/docs/baton/okta

so "C1 release that predates that support" is not something that should be visible here, it's confusing to customers who only deal with one C1 release (whatever is currently deployed).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good Point! Let me fix.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good call — fixed in ec5cffe.

Dropped the release framing in both places (here and the OAuth step at :470), and also the "the connector declares..." phrasing, which is an implementation detail from a reader's side. Both now key off something the reader can actually see: paste the PEM, and if that field only accepts a single line, use the escaped form.

Kept the escaped-form instructions rather than deleting them as legacy — the text area is not live yet, so today every customer still lands on the single-line field, and removing the guidance would leave them stuck on no PEM block found. Phrasing it by observed behaviour means the text stays correct after the C1 side ships too, with no follow-up doc edit needed.

Comment thread docs/connector.mdx Outdated

- For **API Token**: paste your API token into the **API token** field.
- For **OAuth 2.0 Private Key**: enter your **Okta Client ID** and **Okta Private Key ID**, then enter your RSA private key into **Okta Private Key** on a single line, with each line break written as `\n`. See **Private key format** above.
- For **OAuth 2.0 Private Key**: enter your **Okta Client ID** and **Okta Private Key ID**, then paste your RSA private key into **Okta Private Key**. Where that field renders as a text area you can paste the PEM as-is; on a C1 release that predates multiline support, enter it on a single line with each line break written as `\n`. See **Private key format** above.

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.

nit: same here

Review feedback: connector.mdx is published to the c1.ai docs site, where
"a C1 release that predates that support" means nothing to a customer -- they
only ever deal with whatever C1 is currently deployed, and they do not choose a
version. Same objection applies to describing what "the connector declares",
which is an implementation detail from the reader's side.

Both are replaced with an observable condition: paste the PEM, and if the field
only accepts a single line, use the escaped form. A reader can tell which case
they are in by looking at the form, so the text stays correct before and after
the C1 side ships and needs no follow-up edit when it does.

The escaped-form guidance stays rather than being dropped as legacy. The text
area is not live yet, so today every customer still lands on the single-line
field; removing it would leave them on "no PEM block found" with no remedy.

README.md keeps its existing wording -- it is repo-facing rather than published
to the docs site, and was not part of the review comment.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@github-actions github-actions Bot 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.

No blocking issues found.

@haroonkhan-c1
haroonkhan-c1 merged commit 69e5ff9 into main Sep 18, 2026
11 checks passed
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.

4 participants