-
Notifications
You must be signed in to change notification settings - Fork 2
Consolidate: gateway context-switching doc, sandbox image semantics, verify targets #136
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,148 @@ | ||
| # Plan: Switch a Harness between OpenShell and HyperShell | ||
|
|
||
| Status: proposed | ||
|
|
||
| ## Goal | ||
|
|
||
| Run the same Harness file with three operating contexts: | ||
|
|
||
| ```text | ||
| local OpenShell | ||
| HyperShell with personally managed access | ||
| HyperShell with a constrained service account | ||
| ``` | ||
|
|
||
| The first version selects only the gateway, workspace, and connection method. | ||
| It does not move credentials or define security policy. HyperShell guardrails | ||
| come from the service account's workspace membership and gateway-managed | ||
| resources, not from Context behavior. | ||
|
|
||
| CI is an execution environment. It may use the local Context with an ephemeral | ||
| gateway, or the service-account Context when a runner can reach HyperShell. | ||
|
|
||
| ## User experience | ||
|
|
||
| ```bash | ||
| harness apply -f test/ci-workflow.yaml --context contexts/local.yaml | ||
| harness apply -f test/ci-workflow.yaml --context contexts/hypershell-personal.yaml | ||
| harness apply -f test/ci-workflow.yaml --context contexts/hypershell-service-account.yaml | ||
| ``` | ||
|
|
||
| The local Context uses the active OpenShell gateway. The personal HyperShell | ||
| Context uses a gateway registration authenticated by the user through the | ||
| normal OpenShell login flow. The service-account Context uses the existing | ||
| direct OIDC client-credentials path with secret material supplied externally. | ||
|
|
||
| Existing commands without `--context` continue to work. | ||
|
|
||
| ## Context file | ||
|
|
||
| A Context contains one existing Harness `Target`. No new target model or | ||
| templating language is introduced. | ||
|
|
||
| Personal HyperShell uses a normal named gateway registration: | ||
|
|
||
| ```yaml | ||
| apiVersion: harness.openshell.dev/v1alpha1 | ||
| kind: Context | ||
| metadata: | ||
| name: hypershell-personal | ||
| spec: | ||
| target: | ||
| gateway: hypershell | ||
| workspace: personal | ||
| ``` | ||
|
|
||
| The service-account Context uses direct, non-persistent connection metadata: | ||
|
|
||
| ```yaml | ||
| apiVersion: harness.openshell.dev/v1alpha1 | ||
| kind: Context | ||
| metadata: | ||
| name: hypershell-service-account | ||
| spec: | ||
| target: | ||
| workspace: controlled | ||
| registration: | ||
| endpoint: ${HYPERSHELL_GATEWAY} | ||
| oidc: | ||
| issuer: ${HYPERSHELL_OIDC_ISSUER} | ||
| clientId: ${HYPERSHELL_SANDBOX_SA_ID} | ||
| audience: ${HYPERSHELL_OIDC_AUDIENCE} | ||
| ``` | ||
|
|
||
| The workspace names above are examples. They are the main place to distinguish | ||
| personally managed provider state from a centrally managed, narrower service | ||
| account environment. | ||
|
|
||
| `contexts/local.yaml` contains an empty target and therefore uses normal | ||
| OpenShell active-gateway resolution: | ||
|
|
||
| ```yaml | ||
| apiVersion: harness.openshell.dev/v1alpha1 | ||
| kind: Context | ||
| metadata: | ||
| name: local | ||
| spec: | ||
| target: {} | ||
| ``` | ||
|
|
||
| Environment interpolation uses the resolver already used by Harness files. | ||
| `OPENSHELL_OIDC_CLIENT_SECRET` stays in the process environment and is never | ||
| part of a Context, rendered Harness, or structured output. | ||
|
|
||
| ## Resolution | ||
|
|
||
| When `--context` is present: | ||
|
|
||
| 1. Parse the Harness and Context strictly. | ||
| 2. Replace the Harness `spec.target` with the Context target. | ||
| 3. Expand environment references. | ||
| 4. Apply existing target precedence: explicit CLI flag, then `OPENSHELL_*` | ||
| environment, then the resolved target, then the active/default gateway. | ||
| 5. Use that one resolved object for dry-run output and execution. | ||
|
Comment on lines
+101
to
+103
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- design excerpt ---'
sed -n '70,125p' docs/designs/gateway-context-switching.md
printf '%s\n' '--- target and dry-run references ---'
rg -n -C 3 'dry-run|dryrun|context|OIDC_CLIENT_SECRET|clientSecret|client_secret|secret|ResolveTarget|resolved target' \
docs/designs internal cmd --glob '!**/*_test.go' --glob '*.go' --glob '*.md' | head -n 300
printf '%s\n' '--- relevant file list ---'
git ls-files | rg '(^|/)(target|workflow|gateway|context|.*dry.*run).*|docs/designs/gateway-context-switching\.md'Repository: stackrox/harness-openshell Length of output: 21178 🤖 get_repo_knowledge executed:
Length of output: 3570 🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- design excerpt ---'
sed -n '70,125p' docs/designs/gateway-context-switching.md
printf '%s\n' '--- target and dry-run references ---'
rg -n -C 3 'dry-run|dryrun|context|OIDC_CLIENT_SECRET|clientSecret|client_secret|secret|ResolveTarget|resolved target' docs/designs internal cmd --glob '!**/*_test.go' --glob '*.go' --glob '*.md' | head -n 300
printf '%s\n' '--- relevant file list ---'
git ls-files | rg '(^|/)(target|workflow|gateway|context|.*dry.*run).*|docs/designs/gateway-context-switching\.md'Repository: stackrox/harness-openshell Length of output: 22966 🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- design excerpt ---'
sed -n '70,125p' docs/designs/gateway-context-switching.md
printf '%s\n' '--- target and dry-run references ---'
rg -n -C 3 'dry-run|dryrun|context|OIDC_CLIENT_SECRET|clientSecret|client_secret|secret|ResolveTarget|resolved target' docs/designs internal cmd --glob '!**/*_test.go' --glob '*.go' --glob '*.md' | head -n 300Repository: stackrox/harness-openshell Length of output: 21699 🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- apply output and context path ---'
rg -n -C 8 'StructuredOutput|structured output|Output|dry|Context|context|redact|redacted|Marshal|marshal|Resolve' cmd/workflow_apply.go cmd/workflow.go cmd/workflow_apply_test.go internal/config/env.go internal/config/env_test.go
printf '%s\n' '--- exact test body ---'
sed -n '228,285p' cmd/workflow_apply_test.go
printf '%s\n' '--- config target and OIDC types ---'
sed -n '35,75p' internal/config/types.go
sed -n '1,180p' internal/config/env.goRepository: stackrox/harness-openshell Length of output: 50382 🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- dry-run structured output path ---'
sed -n '285,335p' cmd/workflow_apply.go
rg -n -C 12 'TestApplyStructuredOutputRedactsCredentialBearingMaps|renderWorkflow|renderPlan|DryRun|printStructured' cmd/workflow_apply_test.go cmd/*.go
printf '%s\n' '--- plan serialization fields ---'
rg -n -C 8 'type Plan|func .*Plan|Target|Registration|OIDC|printStructured' internal/plan cmdRepository: stackrox/harness-openshell Length of output: 50383 Sensitive Data Exposure (CWE-200): Exposure of Sensitive Information to an Unauthorized Actor Reachability: External · Exploitability: Moderate Redact target values in dry-run structured output. If a target contains 🤖 Prompt for AI Agents |
||
|
|
||
| The Context target is replaced as a whole. Field-by-field merging is not | ||
| supported. | ||
|
|
||
| ## Implementation | ||
|
|
||
| 1. Add a strict `Context` config type containing only metadata and target. | ||
| 2. Add `--context FILE` to `harness apply`. | ||
| 3. Load the Context in `loadWorkflow` and replace `spec.target` before normal | ||
| environment and target resolution. | ||
| 4. Add the three example Context files. | ||
| 5. Run the existing smoke Harness through: | ||
|
|
||
| - a developer's active local gateway; | ||
| - a user-authenticated HyperShell registration; | ||
| - HyperShell using the existing service-account VPN/OIDC setup. | ||
|
|
||
| ## Acceptance | ||
|
|
||
| - The unchanged `test/ci-workflow.yaml` returns exactly | ||
| `canonical-sdk-ok` in all three contexts. | ||
| - `keep: false` removes the sandbox after every run. | ||
| - `harness apply -f file.yaml` behaves exactly as before. | ||
| - Invalid or incomplete Context files fail before gateway access. | ||
| - Dry-run structured output contains the resolved non-secret target and no | ||
| credential values. | ||
| - The personal Context relies on OpenShell's existing login and token refresh. | ||
| - The service-account Context contains no client secret and fails clearly | ||
| before sandbox creation when its OIDC issuer is unreachable off VPN. | ||
|
Comment on lines
+131
to
+132
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win 🔎 Supported by static analysis🤖 get_repo_knowledge executed:
Length of output: 3964 🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- target document ---'
wc -l docs/designs/gateway-context-switching.md
cat -n docs/designs/gateway-context-switching.md | sed -n '1,190p'
printf '%s\n' '--- related references ---'
rg -n -i --glob '!vendor' --glob '!node_modules' 'OIDC|sandbox creation|sandbox-creation|context switching|service-account Context|issuer' . | head -200Repository: stackrox/harness-openshell Length of output: 23177 🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- direct OIDC path ---'
cat -n internal/openshell/sdkclient/direct.go | sed -n '1,145p'
printf '%s\n' '--- workflow construction and execution ---'
cat -n cmd/workflow.go | sed -n '1,110p'
cat -n cmd/workflow_apply.go | sed -n '1,105p'
printf '%s\n' '--- sandbox lifecycle bindings ---'
ast-grep outline internal/run
rg -n 'NewClient|SandboxCreate|CreateSandbox|Create\(|Run|oidcTokenSource|direct' internal/run internal/openshell cmd --glob '*.go' | head -180
printf '%s\n' '--- existing HyperShell acceptance script ---'
cat -n test/hypershell-lifecycle.sh | sed -n '1,125p'Repository: stackrox/harness-openshell Length of output: 38270 🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- client factory and apply call order ---'
cat -n internal/openshell/sdkclient/client.go | sed -n '1,150p'
rg -n -C 8 'sdkclient|NewFrom|New\(|applyWorkflow|buildPlan' cmd internal --glob '*.go' | head -240
printf '%s\n' '--- runner create boundary ---'
cat -n internal/run/runner.go | sed -n '1,115p'Repository: stackrox/harness-openshell Length of output: 24244 Define and test the direct OIDC preflight boundary.
🤖 Prompt for AI Agents |
||
| - The selected service account cannot exceed the workspace role and gateway | ||
| resources assigned to it; Context does not claim to enforce those controls. | ||
|
|
||
| ## Not in this version | ||
|
|
||
| - Provider or model aliases. | ||
| - Provider creation or credential bootstrap. | ||
| - Inference, image, policy, or agent overlays. | ||
| - Context discovery, inheritance, merging, or conditionals. | ||
| - Inline secrets. | ||
| - Managed HyperShell execution from public GitHub runners until network access | ||
| exists. | ||
| - NemoClaw integration. | ||
|
|
||
| Those should be considered only after this target-only switch is useful in | ||
| practice. | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Require lint for
verify-fast.verify-fastdepends onlint, butlintfalls back tovetwhengolangci-lintis unavailable at Lines 69-73. Therefore,make verify-fastcan pass without running lint, although the target is documented asvet + lint. Make this target requiregolangci-lint, or document the fallback explicitly.Suggested fix
📝 Committable suggestion
🧰 Tools
🪛 checkmake (0.3.2)
[warning] 79-79: Target "verify-fast" should be declared PHONY.
(phonydeclared)
🤖 Prompt for AI Agents