Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 80 additions & 56 deletions commands/cfctl.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1050,67 +1050,88 @@ cfctl_failure_guidance_json() {
local comparison_json="{}"
local base_command=""
local requirement_json="{}"
local permission_basis=""

if [[ "${surface}" != "runtime" && "${surface}" != "token" ]] && cfctl_has_surface "${surface}"; then
comparison_json="$(cfctl_compare_permission_all_lanes "${surface}" "${action}" "${operation}")"
recommended_lane="$(cfctl_recommended_lane_from_comparison "${comparison_json}")"
fi

case "${error_code}" in
permission_denied|lane_not_allowed)
if [[ "${action}" == "apply" && -n "${operation}" ]]; then
base_command="$(cfctl_build_apply_command "${surface}" "${operation}" " --plan")"
elif [[ "${action}" == "classify" || "${action}" == "guide" || "${action}" == "can" ]] && [[ -n "${operation}" ]]; then
base_command="$(cfctl_build_verb_command "${action}" "${surface}" "${operation}")"
else
base_command="$(cfctl_build_verb_command "${action}" "${surface}" "${operation}")"
fi
if [[ -n "${recommended_lane}" ]]; then
recommendation_command="$(cfctl_command_with_lane_prefix "${recommended_lane}" "${base_command}")"
next_step="Retry on the recommended lane."
else
recommendation_command="${base_command}"
next_step="Current credentials do not cover this surface; inspect lanes and token scope."
fi
;;
preview_required)
recommendation_command="$(cfctl_command_with_lane_prefix "${recommended_lane}" "$(cfctl_build_apply_command "${surface}" "${operation}" " --plan")")"
next_step="Run the preview first and review the emitted operation_id."
;;
preview_receipt_missing)
recommendation_command="cfctl previews"
next_step="List current preview receipts, then rerun the preview if the expected operation_id is absent."
;;
preview_payload_mismatch)
recommendation_command="$(cfctl_command_with_lane_prefix "${recommended_lane}" "$(cfctl_build_apply_command "${surface}" "${operation}" " --plan")")"
next_step="Selectors, payload, lane, or runtime policy changed. Mint a fresh preview and ack that new operation_id."
;;
preview_lane_mismatch)
recommendation_command="$(cfctl_command_with_lane_prefix "${recommended_lane}" "$(cfctl_build_apply_command "${surface}" "${operation}" " --plan")")"
next_step="Re-run the preview on the same lane you intend to use for the real apply."
;;
preview_version_mismatch|preview_expired)
recommendation_command="$(cfctl_command_with_lane_prefix "${recommended_lane}" "$(cfctl_build_apply_command "${surface}" "${operation}" " --plan")")"
next_step="The reviewed preview is no longer valid. Generate a fresh preview and use its operation_id."
;;
lock_unavailable)
recommendation_command="cfctl locks"
next_step="Inspect active locks and clear only stale ones."
;;
unsafe_secret_sink)
recommendation_command="cfctl token mint ... --value-out /tmp/cloudflare-token.secret"
next_step="Use an absolute non-repo path with mode 600. Repo paths, var/, and symlinks are rejected."
;;
invalid_arguments)
if [[ "${surface}" != "runtime" && "${surface}" != "token" ]] && cfctl_has_surface "${surface}"; then
requirement_json="$(cfctl_requirement_check_json "${surface}" "${action}" "${operation}")"
next_step="Add the missing selectors or choose a valid selector set."
recommendation_command="$(cfctl_build_verb_command "explain" "${surface}")"
fi
;;
*)
;;
esac
permission_basis="$(jq -r '.basis // empty' <<< "${permission_json}")"

if [[ "${permission_basis}" == "zone_resolution_failed" ]]; then
if [[ "${action}" == "apply" && -n "${operation}" ]]; then
base_command="$(cfctl_build_apply_command "${surface}" "${operation}" " --plan")"
elif [[ "${action}" == "classify" || "${action}" == "guide" || "${action}" == "can" ]] && [[ -n "${operation}" ]]; then
base_command="$(cfctl_build_verb_command "${action}" "${surface}" "${operation}")"
else
base_command="$(cfctl_build_verb_command "${action}" "${surface}" "${operation}")"
fi

if [[ -n "${recommended_lane}" ]]; then
recommendation_command="$(cfctl_command_with_lane_prefix "${recommended_lane}" "${base_command}")"
next_step="Retry on a lane that can resolve the zone, or correct the zone selector if it still fails."
else
recommendation_command="$(cfctl_build_verb_command "can" "${surface}" "${operation}" " --all-lanes")"
next_step="The zone selector could not be resolved on the current lane. Verify the zone selector and compare available lanes."
fi
else
case "${error_code}" in
permission_denied|lane_not_allowed)
if [[ "${action}" == "apply" && -n "${operation}" ]]; then
base_command="$(cfctl_build_apply_command "${surface}" "${operation}" " --plan")"
elif [[ "${action}" == "classify" || "${action}" == "guide" || "${action}" == "can" ]] && [[ -n "${operation}" ]]; then
base_command="$(cfctl_build_verb_command "${action}" "${surface}" "${operation}")"
else
base_command="$(cfctl_build_verb_command "${action}" "${surface}" "${operation}")"
fi
if [[ -n "${recommended_lane}" ]]; then
recommendation_command="$(cfctl_command_with_lane_prefix "${recommended_lane}" "${base_command}")"
next_step="Retry on the recommended lane."
else
recommendation_command="${base_command}"
next_step="Current credentials do not cover this surface; inspect lanes and token scope."
fi
;;
preview_required)
recommendation_command="$(cfctl_command_with_lane_prefix "${recommended_lane}" "$(cfctl_build_apply_command "${surface}" "${operation}" " --plan")")"
next_step="Run the preview first and review the emitted operation_id."
;;
preview_receipt_missing)
recommendation_command="cfctl previews"
next_step="List current preview receipts, then rerun the preview if the expected operation_id is absent."
;;
preview_payload_mismatch)
recommendation_command="$(cfctl_command_with_lane_prefix "${recommended_lane}" "$(cfctl_build_apply_command "${surface}" "${operation}" " --plan")")"
next_step="Selectors, payload, lane, or runtime policy changed. Mint a fresh preview and ack that new operation_id."
;;
preview_lane_mismatch)
recommendation_command="$(cfctl_command_with_lane_prefix "${recommended_lane}" "$(cfctl_build_apply_command "${surface}" "${operation}" " --plan")")"
next_step="Re-run the preview on the same lane you intend to use for the real apply."
;;
preview_version_mismatch|preview_expired)
recommendation_command="$(cfctl_command_with_lane_prefix "${recommended_lane}" "$(cfctl_build_apply_command "${surface}" "${operation}" " --plan")")"
next_step="The reviewed preview is no longer valid. Generate a fresh preview and use its operation_id."
;;
lock_unavailable)
recommendation_command="cfctl locks"
next_step="Inspect active locks and clear only stale ones."
;;
unsafe_secret_sink)
recommendation_command="cfctl token mint ... --value-out /tmp/cloudflare-token.secret"
next_step="Use an absolute non-repo path with mode 600. Repo paths, var/, and symlinks are rejected."
;;
invalid_arguments)
if [[ "${surface}" != "runtime" && "${surface}" != "token" ]] && cfctl_has_surface "${surface}"; then
requirement_json="$(cfctl_requirement_check_json "${surface}" "${action}" "${operation}")"
next_step="Add the missing selectors or choose a valid selector set."
recommendation_command="$(cfctl_build_verb_command "explain" "${surface}")"
fi
;;
*)
;;
esac
fi

jq -n \
--arg next_step "${next_step}" \
Expand Down Expand Up @@ -3743,6 +3764,7 @@ cfctl_handle_apply() {
local backend_result="null"
local verification_json
local summary_json
local guidance_json
local id_value

cfctl_require_surface "${surface}"
Expand Down Expand Up @@ -4037,6 +4059,7 @@ cfctl_handle_apply() {
)"

if [[ "${CFCTL_BACKEND_STATUS}" -ne 0 ]]; then
guidance_json="$(cfctl_failure_guidance_json "apply" "${surface}" "mutation_script" "${CFCTL_PERMISSION_JSON}" "execution_failed" "Mutation backend returned a failure" "${operation}")"
cfctl_emit_result \
"false" \
"apply" \
Expand All @@ -4050,7 +4073,8 @@ cfctl_handle_apply() {
"${CFCTL_PLAN_RECEIPT_PATH:-${CFCTL_BACKEND_ARTIFACT_PATH}}" \
"execution_failed" \
"Mutation backend returned a failure" \
"${operation}"
"${operation}" \
"${guidance_json}"
exit 1
fi

Expand Down
66 changes: 66 additions & 0 deletions scripts/verify_static_contract.sh
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,72 @@ jq -e '
and .permission_status.selector_readiness.ready == true
' <<< "${can_upsert_bootstrap_json}" >/dev/null || die "can no-auth upsert posture assertion failed"

email_routing_zone_guidance_json="$(
ROOT_DIR="${ROOT_DIR}" bash <<'BASH'
set -euo pipefail
# shellcheck disable=SC1091
source "${ROOT_DIR}/lib/runtime/cfctl.sh"
# shellcheck disable=SC1091
source "${ROOT_DIR}/commands/cfctl.sh"

cfctl_compare_permission_all_lanes() {
jq -n '
{
active_lane: "dev",
lanes: [
{
lane: "dev",
available: true,
permission: {
state: "unknown",
basis: "zone_resolution_failed",
errors: [],
request: null,
status_code: null,
permission_family: "Email Routing Write"
}
},
{
lane: "global",
available: true,
permission: {
state: "allowed",
basis: "surface_read_probe",
errors: [],
request: {},
status_code: 200,
permission_family: "Email Routing Write"
}
}
],
summary: {
allowed_lanes: ["global"],
denied_lanes: [],
unknown_lanes: ["dev"]
}
}
'
}

cfctl_reset_flags
CF_ACTIVE_TOKEN_LANE="dev"
CFCTL_ZONE_NAME="example.com"
CFCTL_NAME="role@example.com"
CFCTL_SERVICE="maildesk-cf-router"
permission_json='{"state":"unknown","basis":"zone_resolution_failed","errors":[],"request":null,"status_code":null,"permission_family":"Email Routing Write"}'
cfctl_failure_guidance_json "apply" "email.routing_rule" "mutation_script" "${permission_json}" "execution_failed" "Mutation backend returned a failure" "upsert"
BASH
)"
jq -e '
.recommended_lane == "global"
and (.next_step | type == "string" and contains("zone"))
and (.recommended_command | startswith("CF_TOKEN_LANE=global cfctl apply email.routing_rule upsert "))
and (.recommended_command | contains("--zone example.com"))
and (.recommended_command | contains("--name role@example.com"))
and (.recommended_command | contains("--service maildesk-cf-router"))
and (.recommended_command | contains("--plan"))
' <<< "${email_routing_zone_guidance_json}" >/dev/null || die "email routing zone resolution lane guidance assertion failed"

assert_jq_file "permission profile minimality policy" '
.profiles.read.allowed_surfaces != null
and (.profiles.read.allowed_surfaces | index("audit.log")) != null
Expand Down
Loading