Skip to content
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ bootstrap-linux-arm64.sum.txt
# For SKD debugging while building images
spike-sdk-go

# SPIRE source clone (build-spire.sh now uses a temp dir; guard against a
# repo-root clone from older runs or a manual `git clone`).
/spire/

# WSL
*:Zone.Identifier

Expand Down
14 changes: 9 additions & 5 deletions app/nexus/internal/route/acl/policy/delete_intercept.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,21 @@ import (
//
// The function performs the following validations in order:
// - Extracts and validates the peer SPIFFE ID from the request
// - Validates the policy ID format
// - Validates the policy name format
// - Checks if the peer has write permission for the policy access path
//
// If any validation fails, an appropriate error response is written to the
// ResponseWriter and an error is returned.
//
// Parameters:
// - request: The policy deletion request containing the policy ID
// - request: The policy deletion request containing the policy name
// - w: The HTTP response writer for error responses
// - r: The HTTP request containing the peer SPIFFE ID
//
// Returns:
// - *sdkErrors.SDKError: nil if all validations pass,
// ErrAccessUnauthorized if authentication or authorization fails,
// ErrDataInvalidInput if policy ID validation fails
// ErrDataInvalidInput if policy name validation fails
func guardPolicyDeleteRequest(
request reqres.PolicyDeleteRequest, w http.ResponseWriter, r *http.Request,
) *sdkErrors.SDKError {
Expand All @@ -47,7 +47,11 @@ func guardPolicyDeleteRequest(
return authErr
}

return net.RespondErrOnBadPolicyID(
request.ID, w, reqres.PolicyDeleteResponse{}.BadRequest(),
// SPIKE policies are keyed by name; the SDK's PolicyDeleteRequest
// still exposes that identifier as ID, so request.ID holds the policy
// name and must be validated as a name, not as a UUID. See issue #250
// for the pending SDK field rename.
return net.RespondErrOnBadName(
request.ID, reqres.PolicyDeleteResponse{}.BadRequest(), w,
)
}
14 changes: 9 additions & 5 deletions app/nexus/internal/route/acl/policy/get_intercept.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,21 @@ import (
//
// The function performs the following validations in order:
// - Extracts and validates the peer SPIFFE ID from the request
// - Validates the policy ID format
// - Validates the policy name format
// - Checks if the peer has read permission for the policy access path
//
// If any validation fails, an appropriate error response is written to the
// ResponseWriter and an error is returned.
//
// Parameters:
// - request: The policy read request containing the policy ID
// - request: The policy read request containing the policy name
// - w: The HTTP response writer for error responses
// - r: The HTTP request containing the peer SPIFFE ID
//
// Returns:
// - *sdkErrors.SDKError: nil if all validations pass,
// ErrAccessUnauthorized if authentication or authorization fails,
// ErrDataInvalidInput if policy ID validation fails
// ErrDataInvalidInput if policy name validation fails
func guardPolicyReadRequest(
request reqres.PolicyReadRequest, w http.ResponseWriter, r *http.Request,
) *sdkErrors.SDKError {
Expand All @@ -47,7 +47,11 @@ func guardPolicyReadRequest(
return authErr
}

return net.RespondErrOnBadPolicyID(
request.ID, w, reqres.PolicyReadResponse{}.BadRequest(),
// SPIKE policies are keyed by name; the SDK's PolicyReadRequest still
// exposes that identifier as ID, so request.ID holds the policy name
// and must be validated as a name, not as a UUID. See issue #250 for
// the pending SDK field rename.
return net.RespondErrOnBadName(
request.ID, reqres.PolicyReadResponse{}.BadRequest(), w,
)
}
9 changes: 4 additions & 5 deletions app/spike/internal/cmd/policy/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,17 @@ import (

// formatPoliciesOutput formats the output of policy list items based on the
// format flag. It supports human/plain, json, and yaml formats. For human
// format, it creates a readable tabular representation. For JSON/YAML formats,
// it marshals the policies to the appropriate structured format.
// format, it creates a readable list of policy names (policies are keyed by
// name; there is no separate ID). For JSON/YAML formats, it marshals the
// policies to the appropriate structured format.
//
// If the format flag is invalid, it returns an error message.
// If the "policies" list is empty, it returns an appropriate message based on
// the format.
//
// Parameters:
// - cmd: The Cobra command containing the format flag
// - policies: The policy list items to format (contains ID and Name only)
// - policies: The policy list items to format
//
// Returns:
// - string: The formatted output or error message
Expand Down Expand Up @@ -73,7 +74,6 @@ func formatPoliciesOutput(
result.WriteString("POLICIES\n========\n\n")

for _, policy := range *policies {
result.WriteString(fmt.Sprintf("ID: %s\n", policy.ID))
result.WriteString(fmt.Sprintf("Name: %s\n", policy.Name))
result.WriteString("--------\n\n")
}
Expand Down Expand Up @@ -120,7 +120,6 @@ func formatPolicy(cmd *cobra.Command, policy *data.Policy) string {
var result strings.Builder
result.WriteString("POLICY DETAILS\n=============\n\n")

result.WriteString(fmt.Sprintf("ID: %s\n", policy.ID))
result.WriteString(fmt.Sprintf("Name: %s\n", policy.Name))
result.WriteString(fmt.Sprintf("SPIFFE ID Pattern: %s\n",
policy.SPIFFEIDPattern))
Expand Down
5 changes: 2 additions & 3 deletions app/spike/internal/cmd/policy/format_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,9 @@ func TestFormatPoliciesOutput_HumanFormat(t *testing.T) {
t.Error("Human format should contain 'POLICIES' header")
}

// Check policy fields are present (PolicyListItem only has ID and Name)
// The human format prints only the name; policies are keyed by name
// and the vestigial ID is not shown.
expectedFields := []string{
"ID: 123e4567-e89b-12d3-a456-426614174000",
"Name: test-policy",
}

Expand Down Expand Up @@ -200,7 +200,6 @@ func TestFormatPolicy_HumanFormat(t *testing.T) {

// Check all fields are present
expectedFields := []string{
"ID: 123e4567-e89b-12d3-a456-426614174000",
"Name: admin-policy",
"SPIFFE ID Pattern: ^spiffe://example\\.org/admin/.*$",
"Path Pattern: ^.*$",
Expand Down
22 changes: 7 additions & 15 deletions app/spike/internal/cmd/policy/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,31 +51,23 @@ import (
// spike policy list --path-pattern="^secrets/db/.*$"
// spike policy list --spiffeid-pattern="^spiffe://example\.org/app$"
//
// Example output for human format:
// Example output for human format (the list shows policy names only; use
// `spike policy get` for the full details of a policy):
//
// POLICIES
// ========
//
// ID: policy-123
// Name: web-service-policy
// SPIFFE ID Pattern: ^spiffe://example\.org/web-service/.*$
// Path Pattern: ^secrets/db/.*$
// Permissions: read, write
// Created At: 2024-01-01T00:00:00Z
// Created By: user-abc
// --------
//
// Example output for JSON format:
// Example output for JSON format (the "id" field is always empty; policies
// are keyed by name, and the field awaits the SDK rename tracked in issue
// #250):
//
// [
// {
// "id": "policy-123",
// "name": "web-service-policy",
// "spiffeIdPattern": "^spiffe://example\.org/web-service/.*$",
// "pathPattern": "^tenants/demo/db$",
// "permissions": ["read", "write"],
// "createdAt": "2024-01-01T00:00:00Z",
// "createdBy": "user-abc"
// "id": "",
// "name": "web-service-policy"
// }
// ]
//
Expand Down
23 changes: 21 additions & 2 deletions hack/bare-metal/build/build-spire.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,27 @@
# \\\\\\\ SPDX-License-Identifier: Apache-2.0

# This is a simple way to create a single-node SPIRE development setup.
git clone --single-branch --branch v1.11.2 https://github.com/spiffe/spire.git
cd spire || exit
# It builds the SPIRE server and agent from source and installs them into
# /usr/local/bin. The source is cloned into a temporary directory that is
# removed on exit, so the repository working tree stays clean.

set -euo pipefail

SPIRE_VERSION="v1.11.2"

# Clone into a temporary directory and always clean it up on exit, even on
# failure. Leaving the clone behind would pollute the working tree and break
# `make audit` (gofmt scans it).
CLONE_DIR="$(mktemp -d)"
cleanup() {
rm -rf "$CLONE_DIR"
}
trap cleanup EXIT

git clone --single-branch --branch "$SPIRE_VERSION" \
https://github.com/spiffe/spire.git "$CLONE_DIR"

cd "$CLONE_DIR"
go build ./cmd/spire-server
go build ./cmd/spire-agent
sudo mv spire-server /usr/local/bin
Expand Down
Loading
Loading