spike policy
The spike policy
command is the main entry point for managing access
policies in SPIKE. It allows administrators to define, view, and manage rules
that control access to secrets and resources based on workload identity
(SPIFFE ID) and resource paths.
SPIKE provides two commands for managing policies:
spike policy create
—Traditional command-line interface (backward compatibility)spike policy apply
—Enhanced command with YAML file support (recommended for new workflows)
While spike policy create
checks for the existence of a policy, and
errors out if we are overriding an existing policy, spike policy apply
uses
upsert semantics—it will create a new policy if one doesn’t exist, or
update an existing policy if one with the same name already exists. This makes
the spike policy apply
command safe to use in automation and GitOps workflows.
Quick Start
# Using YAML file (recommended)
spike policy apply --file policy.yaml
YAML File Format
Basic Structure
# Policy name - must be unique within the system
name: "web-service-policy"
# SPIFFE ID pattern for workload matching
spiffeid: "spiffe://example.org/web-service/"
# Path pattern for access control
# Note: Trailing slashes are automatically removed during normalization
path: "secrets/web-service/database"
# List of permissions to grant
permissions:
- read
- write
Path Normalization
The apply
command automatically normalizes paths by removing trailing slashes:
# These paths are all normalized to the same value:
path: "secrets/database/production" # ✓ Normalized form
path: "secrets/database/production/" # → "secrets/database/production"
path: "secrets/database/production//" # → "secrets/database/production"
Realistic Path Examples
# Database secrets
name: "database-policy"
spiffeid: "spiffe://example.org/database/"
path: "secrets/database/production"
permissions: [read]
# Web service configuration
name: "web-service-policy"
spiffeid: "spiffe://example.org/web-service/"
path: "secrets/web-service/config"
permissions: [read, write]
# Cache credentials
name: "cache-policy"
spiffeid: "spiffe://example.org/cache/"
path: "secrets/cache/redis/session"
permissions: [read]
# Application environment variables
name: "app-env-policy"
spiffeid: "spiffe://example.org/app/"
path: "secrets/app/env/production"
permissions: [read, list]
All Available Permissions
name: "admin-policy"
spiffeid: "spiffe://example.org/admin/"
path: "secrets"
permissions:
- read # Permission to read secrets
- write # Permission to create, update, or delete secrets
- list # Permission to list resources
- super # Administrative permissions
Alternative YAML Formats
Flow Sequence for Permissions
name: "database-policy"
spiffeid: "spiffe://example.org/database/"
path: "secrets/database/production"
permissions: [read, write, list]
Quoted Values
name: "cache-policy"
spiffeid: "spiffe://example.org/cache/"
path: "secrets/cache/redis"
permissions:
- "read"
- "write"
Creating Policies Using Command-Line Flags
Instead of using a yaml
file, you can provide command-line arguments
to programmatically create your policies too:
# Create your first policy
spike policy create --name=my-service \
--path="secrets/app/" \
--spiffeid="spiffe://example.org/service/" \
--permissions=read
# Verify your policy was created
spike policy list
What are SPIKE Policies?
Policies in SPIKE provide a secure and flexible way to control access to secrets and resources. Each policy defines:
- Who can access resources (via SPIFFE ID patterns)
- What resources can be accessed (via path patterns)
- How resources can be accessed (via permissions)
Policies are the cornerstone of SPIKE’s security model, allowing for fine-grained access control based on workload identity. Using SPIFFE IDs as the foundation, SPIKE ensures that only authorized workloads can access sensitive information.
How Policies Work
When a workload attempts to access a resource in SPIKE:
- The workload presents its SPIFFE ID through a SPIFFE Verifiable Identity Document (SVID)
- SPIKE validates the SVID to verify the workload’s identity
- SPIKE checks if any policy matches both:
- The workload’s SPIFFE ID against the policy’s SPIFFE ID pattern
- The requested resource path against the policy’s path pattern
- If a match is found, SPIKE checks if the requested operation is allowed by the policy’s permissions
- Access is granted only if ALL conditions are met
Why Use Policies?
- Zero Trust Security: Access is based on workload identity, not network location
- Least Privilege: Grant only the permissions needed for each workload
- Auditability: All access is tied to specific policies and identities
- Flexibility: Patterns support regular expression matching, which allows a more fine-grained control over which resources the policy applies to.
- Scalability: Policies work consistently across any deployment size
Features
- Create policies with specific permissions and access patterns
- Apply policies using upsert semantics (create new or update existing)
- List all policies in human-readable or JSON format
- Get policy details by ID or name
- Delete policies with confirmation protection
- Enhanced validation for permissions and parameters
Commands
spike policy list
spike policy list [--format=human|json] [--path=<pattern> | --spiffeid=<pattern>]
Lists all policies in the system. Can be filtered by a resource path pattern or a SPIFFE ID pattern.
Note: --path
and --spiffeid
flags cannot be used together.
spike policy create
spike policy create --name=<name> \
--path=<path-pattern> \
--spiffeid=<spiffe-id-pattern> \
--permissions=<permissions>
Creates a new policy with the specified parameters.
spike policy apply
spike policy apply --file=<policy-file.yaml>
Creates a new policy with file-based input using YAML configuration.
YAML Configuration Format
When using the --file
flag, the YAML file should follow this structure:
name: policy-name
spiffeid: spiffe://example.org/service/
path: secrets/database/production
permissions:
- read
- write
Example Files
SPIKE repository has the following example policies for your convenience:
./examples/policies/sample-policy.yaml
—Basic policy example./examples/policies/test-policies/basic-policy.yaml
—Minimal policy./examples/policies/test-policies/admin-policy.yaml
—Full permissions policy./examples/policies/test-policies/invalid-permissions.yaml
—Example with invalid permissions (for testing)
Permission Types
Permission | Description |
---|---|
read | Allows reading secrets and resources |
write | Allows creating, updating, and deleting secrets |
list | Allows listing resources and directories |
super | Full administrative permissions (use with caution) |
Validation
All policy configurations are validated to ensure:
- Required fields:
name
,spiffeid
,path
, andpermissions
must be present - Valid permissions: Only
read
,write
,list
, andsuper
are allowed - Valid YAML syntax: Proper YAML formatting is required (for YAML files)
- Non-empty values: All fields must have non-empty values
GitOps Integration
YAML files can be easily integrated into GitOps workflows:
-
Store policy YAML files in a Git repository
policies/ ├── web-service-policy.yaml ├── database-policy.yaml └── admin-policy.yaml
-
Use CI/CD pipelines to validate policies before deployment
# Validation step in CI for policy in policies/*.yaml; do spike policy apply --file "$policy" # - ensure that the policy is created # - delete the policy # - ensure that the policy is gone done
-
Apply policies using
spike policy apply --file
in deployment scripts# Deployment script for policy in policies/*.yaml; do spike policy apply --file "$policy" done
-
Version control changes to policies alongside application code
-
Use upsert semantics to safely apply policy changes without worrying about conflicts
spike policy get
spike policy get <id> [--format=human|json]
spike policy get --name=<name> [--format=human|json]
Gets details of a specific policy by ID or name. Use --format=json
for machine-readable output.
spike policy delete
spike policy delete <id>
spike policy delete --name=<name>
Deletes a policy by ID or name. Requires confirmation.
Usage Examples
# Create a policy for a web service with read and write access
spike policy create \
--name=web-service \
--path="secrets/web/" \
--spiffeid="spiffe://example.org/web/" \
--permissions=read,write
# Create a policy with multiple permissions
spike policy create \
--name=admin-service \
--path="secrets/" \
--spiffeid="spiffe://example.org/admin/" \
--permissions=read,write,list
# Apply a policy using a YAML file
spike policy apply --file=policy.yaml
# List all policies in JSON format (useful for automation)
spike policy list --format=json
# Get details of a specific policy by name
spike policy get --name=web-service
# Get policy details in JSON format
spike policy get --name=web-service --format=json
# Delete a policy and confirm deletion
spike policy delete --name=web-service
Pattern Syntax
SPIKE policies support regular expression pattern matching for both SPIFFE IDs and resource paths:
- If the pattern is a single
"*"
, then it matches anything. - For any other pattern, the pattern is compiled as a “regular expression”.
This would mean, for an exact match, you would need to include ^
and $
in
your patterns as well.
For example:
secrets/db
matchesglobal/secrets/db
andsecrets/db/local
- Whereas,
^secrets/db$
only matchessecrets/db
and nothing else (global/secrets/db
andsecrets/db/local
will not match)
Thus, for precise control, you might want to include ^
and $
at the
beginning and end of your patterns respectively for an exact match.
How Regular Expressions are Used For Policy Matching
More specifically, SPIKE compiles SPIFFE ID patterns and path patterns defined in the policies into regular expressions.
Here is a simplified version of how this regular expression compilation happens behind-the-scenes:
pathRegex, err := regexp.Compile(policy.PathPattern)
// ... error handling omitted for brevity.
policy.PathRegex = pathRegex
// `pathRegEx` is used for policy validation.
As seen from the example above, both the path pattern and the SPIFFE ID pattern that are provided during policy creation which are used “AS IS” to create regular expression matchers. These patterns are compiled into Go’s built-in regex engine, ensuring that the matching process strictly adheres to the patterns defined in the policy, allowing for precise and flexible access control.
Simplicity Is the Key
Because of the regular expression usage in SPIKE policies, a policy create
operation can define more flexible matching patterns. However, keeping patterns
simple is both more secure and easier to manage and reason about. Creating a
pattern that is too broad or that uses overly complex regular expressions may
lead to unintended consequences and security risks. Simplicity is important
to ensure patterns are clear, predictable, and effective.
When a workload attempts to access a resource, its SPIFFE ID and the requested resource path are matched against these compiled regular expressions. This ensures that both identity and resource patterns follow the specified rules and allow for flexibility with wildcards or exact matches.
Path Pattern Examples
secrets/ # All resources in the secrets directory
secrets/database/ # Only resources in the database subdirectory
secrets/database/creds # Only the specific creds resource
# You can provide regular expressions for a more fine-tuned
# pattern match:
^secrets/db-[123]$ # Matches secrets/db-2, but not secrets/db-4.
Path Patterns in SPIKE
Path patterns in SPIKE are designed to provide flexibility but also follow certain conventions for clarity and usability. While the path pattern is suggested (but not mandated) to look like a UNIX-style path for familiarity, SPIKE secret paths DO NOT start with a leading slash.
This is because SPIKE paths represent logical key namespaces, not hierarchical filesystem paths. They are always relative to the secrets engine mount point, making the leading slash redundant and potentially confusing.
Example:
- Correct:
secrets/app/config
- Redundant/Confusing:
/secrets/app/config
Additionally, although there is currently no restriction on how the path is formed, it is worth noting that future versions of SPIKE may restrict paths from having a trailing slash to avoid ambiguity and maintain consistency in naming practices.
Best Practices for Path Patterns:
- Avoid leading slashes.
- Avoid trailing slashes to ensure forward compatibility.
- Use descriptive and meaningful names that reflect the resource’s purpose or hierarchy.
SPIFFE ID Pattern Examples
spiffe://example.org/ # Workloads in the example.org trust domain
spiffe://example.org/web/ # Only web workloads
^spiffe://example.org/web/server$ # Only the specific web server workload
Best Practices
- Follow the principle of least privilege when assigning permissions
- Use descriptive policy names that reflect their purpose
- Create separate policies for different workload types
- Use specific path patterns rather than overly broad ones
- Regularly audit and review your policies
- Never assign
super
permissions unless absolutely necessary
spike
Command Index
spike secret
: Manage secrets.spike policy
: Manage rules that control access to secrets.spike operator
: Administrative functionality for system operations and disaster recovery.