Skip to content

Ensure BMC access only when demanded - #7375

Closed
briansrls wants to merge 1 commit into
agent/bmc-typed-operationsfrom
agent/bmc-access-ensure
Closed

briansrls wants to merge 1 commit into
agent/bmc-typed-operationsfrom
agent/bmc-access-ensure

Conversation

@briansrls

Copy link
Copy Markdown
Contributor

What changed

Makes BMC credential access an ensure/upsert consequence of an unmet access requirement.

  • Reuses an already materialized credential when valid access exists.
  • Requests human gcloud authentication only when the demanded secret cannot otherwise be resolved.
  • Models access-token and secret-materialization receipts explicitly.
  • Adds a Redfish netrc-over-stdin operation for onboarding probes so secret material does not enter argv.
  • Extends mocks and refusal witnesses for the new capability surface.

Why

Human authentication is not an unconditional phase of subsumption; it is one possible realization of a missing access capability. Modeling it this way keeps eventual OAuth replacement local to the access provider and prevents BMC reconciliation from owning ad hoc login steps.

Stack

Depends on #7374.

  1. Bind durability evidence to admitted state #7371 generic durability carrier and witnesses
  2. Record versioned BMC capabilities and live receipts #7372 BMC/Linux capability facts and typed live receipts
  3. Model BMC desired state and reconciliation #7373 BMC desired state and reconciliation
  4. Define typed OpenBMC fan operations #7374 typed OpenBMC operation realization
  5. This PR: demand-derived BMC access ensure
  6. Live actuator and rollback receipt

Supersedes the authentication portion of draft #7338. It does not include the generic interpreter redaction change requested for separate treatment.

Validation

  • BMC authentication/runtime-secret focused witnesses: 8/8
  • Secret-bearing onboarding transport uses stdin, not argv
  • Whole-tree compile-clean and build-artifact verification pass

@gunbai-bot

gunbai-bot Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Superseded — the access-ensure fixes are assigned to #7423 (delete the eager legacy secret_ref_credential authority, preserve the typed refusal cause through every adapter instead of collapsing UpsertRequired and FetchRefused to Absent, represent the human step as a closed type rather than carrying "gcloud auth login" as executable data, replace the concat-based netrc serializer, and remove -k from any path used as convergence evidence).

Closing loses nothing: this head (b9ad3bcd86) is an ancestor of #7428, and the agent/bmc-access-ensure branch is retained, so the original diff stays available as the reference for that work.

— sent from quiet-wren-607

@gunbai-bot gunbai-bot Bot closed this Jul 29, 2026
briansrls added a commit that referenced this pull request Jul 30, 2026
…ling, circular activation proof, static-digest detachment; split suitability / durability qualification / ordinary convergence) + #7375 access ensure (delete the eager legacy credential authority, preserve typed refusal causes, no (#7423)

* Bind durability evidence to admitted state

* Record versioned BMC capabilities and live receipts

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* Use canonical carriers in BMC proof receipts

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* Use canonical HTTP status carrier for BMC reset

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* Regenerate signed temperature delta carriers

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* Regenerate canonical positive measure carrier

* Model BMC desired state and reconciliation

* WIP: BMC stack C: #7373 policy reconciliation (HARD BLOCK: evidence relabelin

* WIP: BMC stack C: #7373 policy reconciliation (HARD BLOCK: evidence relabelin

* WIP: BMC stack C: #7373 policy reconciliation (HARD BLOCK: evidence relabelin

* fix: repair fleet_bmc_state parse error blocking CI regen

The durability-evidence constructor used else-if chains and multiline ||
conditions the .dag parser rejects; refactor to bool-match helpers and
define GoogleCloudInteractiveAuthenticationRequired as a closed type.

Co-authored-by: Cursor <cursoragent@cursor.com>

* WIP: BMC stack C: #7373 policy reconciliation (HARD BLOCK: evidence relabelin

* fix: resolve BMC credential materialization typecheck failures

Move shell.GCloud.AuthPrintAccessToken into extdeps.shell with an exit_success
field, add credential materialization helpers, and update srv3 actuate paths to
match on BmcCredentialMaterialization instead of Optional Present/Absent.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: firmware-track Conflict precedes projection gate; align witness verdict

Refuse off-track observed firmware with Conflict before the projection-absent
arm, and expect UnknownRefused when major-3 firmware carries a wrong minor
projection capability.

Co-authored-by: Cursor <cursoragent@cursor.com>

* docs: declare bmc_bootstrap_provision eager token fork as dissolve-on follow-on

Name the pre-existing shell.GCloud.AuthPrintAccessToken site beside
ensure_access_token so the second authority is counted, not forgotten (#7425).

Co-authored-by: Cursor <cursoragent@cursor.com>

* WIP: BMC stack C: #7373 policy reconciliation (HARD BLOCK: evidence relabelin

* WIP: BMC stack C: #7373 policy reconciliation (HARD BLOCK: evidence relabelin

* fix: align fan hysteresis with frozen carrier PositiveCelsiusDelta

Mechanical follow-on to rebasing #7423 onto carrier base 5dee646.

Co-authored-by: Cursor <cursoragent@cursor.com>

* WIP: BMC stack C: #7373 policy reconciliation (HARD BLOCK: evidence relabelin

* fix: migrate firmware intent check to typed verdict on carrier b70c484

Replace deleted Bool predicate with bmc_firmware_observation_intent_verdict;
Mismatch arms thread required/observed into located refusal reasons.

Co-authored-by: Cursor <cursoragent@cursor.com>

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* fix: migrate fleet BMC durability evidence to sunny-crab typed-order receipts

Rebase consumer onto carrier d8d15c5: drop StateDurabilityTimeline, use
StateBefore/AfterReadbackReceipt and perturbation timing fields derived from
the reboot receipt without storing instants twice.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: refuse AdmittedConfigDigestUnavailable instead of fabricating digest

Replace the non-fleet bmc_fan_admitted_config_digest else-branch sentinel
with a typed Unavailable variant; capability construction now takes an
explicit admitted digest. Witness sentinel renamed for observation-only
mismatch controls.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: construction-wall linux publication commit + derive capability hash

Replace hand-rolled record field matching with a unit variant
(LinuxSynchronizedRenameReplacePublication) as the single synchronized
authority; derive durability capability definition_hash from the
publication variant. Mark realization definition hashes as label-backed
scaffold pending swift-boar actuator mechanical derivation.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Make durability proof gaps explicit

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* WIP: BMC stack C: #7373 policy reconciliation (HARD BLOCK: evidence relabelin

* Repair positive measure seed realization

* fix: repair std_measure.rs enum variant broken by carrier regen

Restore PositiveMeasureCountBuilt after a mechanical regen rewrite
mistook the enum arm for a Measure constructor, which broke cargo fmt
and the build gate on 199a777.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: refuse non-positive reboot timing; dissolve linux Bool predicate

Address review 44783 (codex REQUEST_CHANGES):
- Replace fabricated 1ms fallback in bmc_fan_receipt_elapsed_millisecond
  with BmcFanRebootTimingReceipt that typed-refuses
  DurabilityReceiptNonPositiveInterval for zero/negative intervals.
- Delete linux_file_publication_has_synchronized_commit Bool predicate;
  match LinuxFilePublicationProtocol coproduct directly at consumers.
- Add reboot_durability_evidence_refuses_non_positive_interval witness.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Close positive measure and parser review gaps

* WIP: BMC stack C: #7373 policy reconciliation (HARD BLOCK: evidence relabelin

* fix: dissolve coproduct Bool predicates flagged in review 44803

Route firmware intent and durability commit decisions through canonical
typed verdict/query surfaces: bmc_firmware_version_intent_verdict for
pin/track checks, DurabilityCommitBarrier match for synchronized commit,
and remove publication-protocol Bool re-encoding from apply suitability.

Co-authored-by: Cursor <cursoragent@cursor.com>

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* fix: repair bmc_converge.dag parse error from mismatched braces

Close the nested match arms in firmware classification and fan-policy
classification that caused heal/regen to fail with expected LParen.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: restore secret_manager module import for AccessVersion binding

The stack C migration deleted import extdeps.cloud.gcp.gcp but left
gcp.SecretManager.AccessVersion in fetch_secret_ref_credential; bind
the service through extdeps.cloud.gcp.secret_manager where it is defined
(review 44815).

Co-authored-by: Cursor <cursoragent@cursor.com>

* Close durability qualification bypass

* fix: close review 44832 gaps and bind durability evidence to receipt capability

Record perturbation_capability on BmcFanRebootPersistenceReceipt so evidence
construction cannot relabel via a separate caller argument; consume
asrock_altrad8ud_factory_fan_config_digest for previous_config_digest;
dissolve remaining Bool predicates into typed persistence and durability
verdict matches (review 44832).

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: break bmc_fan_projection <-> fleet_bmc_observation import cycle

Move srv4 projection capability and reboot receipt back to fleet_bmc_state;
relocate bmc_fan_admitted_config_digest to fleet_bmc_observation beside the
digest authority; drop bmc_fan_projection's observation import so combined
actuator compile is acyclic (swift-boar-810).

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: parameterize bmc_fan_admitted_config_digest per reconcile spine

Projection takes caller-supplied digest (optional absence → Unavailable);
observation no longer owns admission logic or srv4 hardcoding. Breaks the
bmc_fan_projection ↔ fleet_bmc_observation cycle without a third module.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: derive projection config digest from curve+realization

Ground projected_config_digest in bmc_fan_projection from intent curve
and realization identity, not srv4_bmc_fan_active_config_digest observation.
Restores non-tautological live-digest and durability admission checks
(review 44861).

Co-authored-by: Cursor <cursoragent@cursor.com>

* WIP: BMC stack C: #7373 policy reconciliation (HARD BLOCK: evidence relabelin

* fix: typed access-ensure refusals and credential probe upsert arms

Classify gcloud print-access-token failures by stderr: only observed auth
deficits yield Apply(interactive auth); infrastructure failures Refuse.
Preserve AccessTokenUpsertRequired/EnsureRefused through BmcCredentialProbeResult
instead of erasing into CredentialStateUnknown (review 44879).

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: execute projection digest sha256 derivation and address review 44897

Ground the fleet-quiet projected config digest on one cited hex authority
consumed through sha256_digest(hex: …), add a curve-step fingerprint pin,
and witness the executed equality so digest drift cannot pass guards silently.

Co-authored-by: Cursor <cursoragent@cursor.com>

* WIP: BMC stack C: #7373 policy reconciliation (HARD BLOCK: evidence relabelin

* fix: preserve durability construction refusal and dissolve power predicate

Keep srv4 durability evidence as BmcFanDurabilityEvidenceConstruction and
propagate typed construction refusals through classification instead of
erasing to an empty evidence list. Replace the hand-rolled RedfishPowerState
Bool predicate with redfish_host_power_state_continuity_verdict.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: exhaust StateDurabilityRefusal arms in fan durability reasons

Remove the absorbing wildcard in bmc_fan_durability_refusal_reason so each
StateDurabilityRefusal variant surfaces a located diagnostic, and witness
the generation-mismatch arm executes with distinct prose.

Co-authored-by: Cursor <cursoragent@cursor.com>

* WIP: BMC stack C: #7373 policy reconciliation (HARD BLOCK: evidence relabelin

* WIP: BMC stack C: #7373 policy reconciliation (HARD BLOCK: evidence relabelin

* fix: dissolve BmcFanDutyDecision predicates onto canonical surface

Add curve and sensor-unavailable duty accessors on extdeps.bmc.types and
route thermal witnesses through them instead of local has_* Bool predicates.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: dissolve BmcFanControllerShape topology onto canonical accessors

Add aggregated/independent topology accessors on extdeps.bmc.types and route
bmc_fan_policy_projection_topology_matches plus the controller-shape witness
through them instead of coproduct Bool predicates.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Merge remote-tracking branch 'origin/main' into session/loyal-owl-29

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: address review 45050 single-authority and construction gaps

Ground gcloud auth-deficit stderr classification in extdeps.cloud.gcp,
replace tautological linkage Bool with an exhaustive match gate, guard
BMC credential refusal NonEmptyStr refinement, and dissolve parallel
materialization walkers into caller pattern matches.

Co-authored-by: Cursor <cursoragent@cursor.com>

* WIP: BMC stack C: #7373 policy reconciliation (HARD BLOCK: evidence relabelin

* fix: block partial linkage admission and bind projected digest identity

Require every realization role and capability linkage slot to carry
evidence before admission; fold unavailable assertions conjunctively.
Replace recomputed curve fingerprint pins with a frozen
BmcProjectedConfigContentIdentity row tying probed curve bytes to the
cited sha256 hex (review 45067).

Co-authored-by: Cursor <cursoragent@cursor.com>

* WIP: BMC stack C: #7373 policy reconciliation (HARD BLOCK: evidence relabelin

* fix: close fan-policy suitability refusal causes in bmc_converge

Replace String refusal leaves with typed BmcFanConfigPersistenceApplyRefusalCause
and FanPolicySuitabilityRefusalCause coproducts; wrap persistence-apply refusals
rather than flattening across domains (quiet-wren-607).

Co-authored-by: Cursor <cursoragent@cursor.com>

* WIP: BMC stack C: #7373 policy reconciliation (HARD BLOCK: evidence relabelin

* WIP: BMC stack C: #7373 policy reconciliation (HARD BLOCK: evidence relabelin

* Mark gcloud stderr auth-deficit classifier as dissolve-on heuristic.

The review 45108 nit is honest: substring matching over English stderr is
fail-closed today but fragile. Name the structured auth-status replacement
and route classification through the single pattern-table authority.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Brian <briansrls@MacBook-Pro.local>
Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
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