config: render the Okta private key as a multiline field - #214
Conversation
Connector PR Review: config: render the Okta private key as a multiline fieldBlocking Issues: 0 | Suggestions: 0 | Threads Resolved: 0 Review SummaryThe full PR diff was scanned for security and correctness: Security IssuesNone found. Correctness IssuesNone found. SuggestionsNone. |
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>
c1bb0e3 to
db7a48f
Compare
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>
…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>
There was a problem hiding this comment.
🟢 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-keyfromfield.StringFieldtofield.MultilineFieldwhile retainingWithIsSecret(true). - Refresh documentation to explain multiline UI behavior and the fallback
\n-escaped format for older C1 releases. - Update
config_schema.jsonto emitSTRING_FIELD_TYPE_MULTILINEforokta-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.
baton-sdk version 0.31.0 has landed. This is a stale review.
| **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`: |
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
Good Point! Let me fix.
There was a problem hiding this comment.
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.
|
|
||
| - 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. |
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>
Summary
okta-private-keyholds 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 withfield.MultilineFieldmakes the UI render a masked textarea instead.pkg/config/config.go.WithIsSecretis retained — multiline is its ownStringFieldTyperather than a modifier, butis_secretlives onField, so the two still compose and the value stays sealed and write-only server side.pkg/config/conf.gen.gois deliberately unchanged.MultilineFieldleaves the field's type as plain text, soOktaPrivateKeystays a Gostringand nothing inpkg/connectororpkg/oktaauthneeds to change. (Modelled as a file-upload field instead, the generated type would have become[]byteand both would have needed updating.)Requires
field.MultilineFieldfrom ConductorOne/baton-sdk#1139, released inv0.31.0. That has landed — main is already onv0.31.0via baton-admin, and this branch is rebased on top, so nogo.modchange is needed here and nothing blocks merge.Test plan
go build ./...against the real releasedv0.31.0(no localreplace)go generate ./...leavespkg/config/conf.gen.gounchanged;OktaPrivateKeyis stillstringgo test ./...passes (pkg/connector,pkg/oktaauth)baton-okta configemits"type": "STRING_FIELD_TYPE_MULTILINE"onokta-private-keywith"isSecret": truepreserved, andapi-tokenunaffectedconfig_schema.jsonregenerated by the metadata workflow picks up the new field type🤖 Generated with Claude Code