Generation, proof, publication, and merging are separate steps on purpose. Nothing reaches your repository until you publish, and nothing lands on your default branch until you merge.
Generate
cf fix generate <finding-id>
cf fix generate <finding-id> --wait--wait polls until the patch settles, for up to about three minutes. Without it you get generating back and poll cf fix show yourself. Starting a second generation while one is running fails with fix_in_progress rather than doing the work twice.
Read the diff
cf fix show <finding-id>
cf fixcf fix with no argument lists every finding grouped by the state of its patch: ready, opened, merged, still generating, failed, or no patch yet. cf fix show prints one patch, its explanation, and the pull request URL if one exists.
Prove it
cf proof run <finding-id> --wait
cf proof show <finding-id>
cf proofA proof checks the patch against the finding, with no model involved. A dependency finding is checked against the vulnerable version range, a leaked credential against the code it was found in, and a code finding by running its reproduced attack in a sandbox against the code before and after the patch, with a legitimate input alongside. A proof starts only when explicitly requested; generating a patch does not start one. Bare cf proof lists every proof in the last scan.
| Verdict | What it means |
|---|---|
proven | The attack worked before the patch and was blocked after it, both observed by running them. |
incomplete | Nothing was proved either way, and the summary says why: the attack never worked against the scanned code, the code could not start, or a person still has to confirm a rotation. None of these says the patch is wrong. |
refuted | The patch does not close the finding. Publishing it is refused. |
unprovable | There was nothing to prove. |
cf proof show prints the checks, what each one found, and the witness: the attack that was run, where it enters, and what should now fail instead. A patch a proof refuted cannot be published, and regenerating the patch starts the proof over, because a proof is bound to the exact patch it ran against.
cf proof attest <finding-id>
cf proof attest <finding-id> --note "revoked in the AWS console"A leaked credential settles as incomplete even with a perfect patch, because taking a key out of the code does not revoke it at the provider. Only you know whether it was. Attesting records that under your name in the audit log, and it is the one part of a proof a person supplies rather than a machine.
Give a proof what the app needs to boot
cf proof env
cf proof env set DATABASE_URL
printf %s "$DATABASE_URL" | cf proof env set DATABASE_URL --stdin
cf proof env set DATABASE_URL --from-env
cf proof env unset DATABASE_URLA proof that attacks the running app has to start it first, and the app may need a database URL or an API key to do that. These values are stored per repository, encrypted, and never shown again: cf proof env lists names only. set asks for the value with a masked prompt, or reads it from stdin or from your shell, never from an argument, so it stays out of your history. Replacing a value and unset both ask first. Use test credentials: the value goes into a sandbox that runs an attack.
Publish
cf fix publish <finding-id>This creates a branch, commits the patch, and opens a pull request. You are asked to type the repository name to confirm, so there is no accidental pull request. Publishing twice returns the pull request that already exists rather than opening a second one.
Merge
cf fix merge
cf fix merge <finding-id>
cf fix merge <finding-id> --method rebase --no-delete-branch| Flag | Values | Default |
|---|---|---|
--method | merge, squash, rebase | squash |
--no-delete-branch | flag | the branch is deleted after merging |
With no finding id, cf fix merge offers the open pull requests to choose from, or merges straight away when there is only one.
When merging refuses
| Error code | What happened | What to do |
|---|---|---|
pull_request_blocked | A required review or status check is pending | Wait for it. Do not work around it. |
pull_request_conflicted | The branch conflicts with its base | Rebase or regenerate the patch against a newer scan. |
pull_request_draft | It is still a draft | Mark it ready on the provider. |
pull_request_closed | It was closed without merging | Nothing to merge. Generate again if you still want it. |
fix_not_published | No pull request exists yet | Publish first. |
Then rescan
cf scan --wait
cf reproduced --severity critical,high
cf commits --limit 1Merging changes the code. The rescan is what records the finding as resolved. See Pull requests.
Have a correction or need help?
Email the docs team