This document is for an unreleased version of Crossplane.

This document applies to the Crossplane master branch and not to the latest release v1.20.

Provider capabilities are declarative features that providers can implement to change their behavior and integration with Crossplane. Capabilities enable providers to opt into new features while maintaining backward compatibility.

What are provider capabilities

Provider capabilities are metadata declarations in provider packages that tell Crossplane how the provider should behave. They’re like feature flags but you declare them at the package level.

1# In provider package metadata
2apiVersion: meta.pkg.crossplane.io/v1alpha1
3kind: Provider
4metadata:
5  name: provider-aws
6spec:
7  capabilities:
8  - safe-start
9  - CustomCapability

Crossplane reads these capabilities and modifies its behavior when installing and managing the provider.

Available capabilities

safe-start

The safe-start capability changes how Managed Resource Definitions (MRDs) are activated when you install the provider.

Without safe-start:

  • All resources become MRDs that are automatically active
  • Active MRDs create corresponding CRDs
  • Compatible with legacy providers and existing workflows

With safe-start:

  • All resources become MRDs that start in Inactive state
  • No CRDs until you explicitly activate MRDs
  • Reduces initial resource overhead and improves performance
1spec:
2  capabilities:
3  - safe-start
Tip
safe-start is valuable for large providers like AWS that define hundreds of managed resources. It prevents performance issues by avoiding the creation of unused CRDs.

When to use safe-start

Use safe-start when:

  • Your provider defines over 50 managed resources
  • Users typically need only a subset of available resources
  • Installation performance and resource usage are concerns
  • You want to provide better resource discovery through MRDs

Don’t use safe-start when:

  • Your provider has under 20 managed resources
  • Most users need all available resources
  • Backward compatibility with existing installations is critical
  • Your users aren’t ready to manage resource activation

Capability matching

Crossplane supports flexible matching for capability names:

  • Exact match: safe-start
  • Case variations: SafeStart, safestart, safe-start
  • Fuzzy matching: Handles common spelling variations

This flexibility prevents issues when providers use different naming conventions.

How capabilities affect installation

The provider installation process changes based on declared capabilities:

flowchart TD
    install[Install Provider Package]
    readCaps[Read Capabilities]
    checkSafe{Has safe-start?}
    activateAll[Activate All MRDs]
    keepInactive[Keep MRDs Inactive]
    createCRDs[Create All CRDs]
    waitPolicy[Wait for Activation Policy]
    
    install --> readCaps
    readCaps --> checkSafe
    checkSafe -->|No| activateAll
    checkSafe -->|Yes| keepInactive
    activateAll --> createCRDs
    keepInactive --> waitPolicy
    
    style keepInactive fill:#c8e6c9
    style waitPolicy fill:#fff3e0

Provider compatibility

Legacy providers

Providers without any capabilities work as before:

  • All MRDs are active by default
  • Crossplane creates all CRDs when provider installs
  • No changes required for existing compositions or configurations

Modern providers

Providers with safe-start capability require extra setup:

  • Create ManagedResourceActivationPolicy to activate needed resources
  • Verify required CRDs exist before creating managed resources
  • Use MRD connection details documentation for resource planning

Implementing safe-start in providers

safe-start implementation requires several technical changes to provider code and build processes. This section provides an overview - see the complete safe-start implementation guide for detailed instructions.

Key implementation requirements

Code changes:

  • Add MRD controller logic to handle activation/deactivation
  • Support both namespaced and cluster-scoped resources
  • Generate MRDs with connection details documentation
  • Implement CRD lifecycle management

Build process changes:

  • Update Makefile to generate MRDs alongside CRDs
  • Change CI/CD to test safe-start behavior
  • Include MRDs in provider package artifacts

RBAC updates: safe-start providers need extra permissions to manage CRDs dynamically:

 1apiVersion: rbac.authorization.k8s.io/v1
 2kind: ClusterRole  
 3metadata:
 4  name: my-provider-system
 5rules:
 6# Standard provider permissions
 7- apiGroups: [""]
 8  resources: ["events"]
 9  verbs: ["create", "update", "patch"]
10  
11# Additional safe-start permissions
12- apiGroups: ["apiextensions.k8s.io"]
13  resources: ["customresourcedefinitions"] 
14  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
15- apiGroups: ["apiextensions.crossplane.io"]
16  resources: ["managedresourcedefinitions"]
17  verbs: ["get", "list", "watch", "update", "patch"]

Provider package metadata

Declare safe-start capability in your provider package:

1apiVersion: meta.pkg.crossplane.io/v1
2kind: Provider
3metadata:
4  name: my-provider
5spec:
6  package: registry.example.com/my-provider:v2.0.0
7  capabilities:
8  - safe-start

Managed resource definition generation with connection details

Generate MRDs that document connection details for better user experience:

 1apiVersion: apiextensions.crossplane.io/v1alpha1
 2kind: ManagedResourceDefinition
 3metadata:
 4  name: databases.rds.aws.example.io
 5spec:
 6  group: rds.aws.example.io
 7  names:
 8    kind: Database
 9    plural: databases
10  scope: Namespaced
11  
12  # Connection details documentation
13  connectionDetails:
14  - name: endpoint
15    description: "The RDS instance connection endpoint"
16    type: string
17    fromConnectionSecretKey: endpoint
18  - name: port
19    description: "The port number for database connections" 
20    type: integer
21    fromConnectionSecretKey: port
22  - name: username
23    description: "The master username for the database"
24    type: string
25    fromConnectionSecretKey: username
26  - name: password
27    description: "The master password for the database"
28    type: string
29    fromConnectionSecretKey: password

Implementation examples

The provider-nop safe-start implementation demonstrates:

  • Adding both namespaced and cluster-scoped resource variants
  • MRD controller integration
  • Build process updates for safe-start support
  • Testing strategies for safe-start behavior
Tip
See the complete safe-start implementation guide for step-by-step instructions, code examples, and testing strategies.

Migration considerations

When adding safe-start to existing providers:

Backward compatibility:

  • Existing provider installations continue working unchanged
  • New installations start with inactive MRDs
  • Provide migration documentation for users

Version strategy:

1# Document version compatibility clearly
2# Provider v1.x: Traditional CRD installation  
3# Provider v2.0+: safe-start support with MRDs

Best practices

For provider developers

Do use safe-start when:

  • Your provider has >50 managed resources
  • Resource activation patterns vary by environment
  • Performance optimization is important

Document capabilities:

  • Explain what each capability does
  • Provide migration guides for existing users
  • Include examples of activation policies

Test compatibility:

  • Verify behavior with and without capabilities
  • Test with different Crossplane versions
  • Validate RBAC permissions

For platform operators

Plan activation policies:

 1# Development environment - minimal resources
 2apiVersion: apiextensions.crossplane.io/v1alpha1
 3kind: ManagedResourceActivationPolicy
 4metadata:
 5  name: dev-resources
 6spec:
 7  activations:
 8  - "databases.*.example.com"
 9  - "buckets.*.example.com"
10
11---
12# Production environment - comprehensive resources  
13apiVersion: apiextensions.crossplane.io/v1alpha1
14kind: ManagedResourceActivationPolicy
15metadata:
16  name: prod-resources
17spec:
18  activations:
19  - "*.example.com"  # Activate all resources

Track activation status:

1# Check which MRDs are active
2kubectl get mrds -l provider=my-provider
3
4# Verify activation policies
5kubectl get mrap -o wide
6
7# Monitor resource usage
8kubectl top nodes

Troubleshooting capabilities

Common issues

MRDs not activating:

1# Check if provider has safe-start capability
2kubectl get provider my-provider -o yaml | grep -A5 capabilities
3
4# Verify activation policy exists and matches
5kubectl get mrap
6kubectl describe mrap my-policy

CRDs not created:

1# Check MRD activation status
2kubectl get mrd my-resource.example.com
3
4# Look for controller errors
5kubectl logs -n crossplane-system deployment/crossplane

Provider installation fails:

1# Check provider conditions
2kubectl describe provider my-provider
3
4# Look for RBAC issues
5kubectl get events --field-selector reason=FailedCreate

Debug commands

1# List all providers and their capabilities
2kubectl get providers -o jsonpath='{range .items[*]}{.metadata.name}: {.spec.capabilities[*].name}{"\n"}{end}'
3
4# Check MRD activation across providers
5kubectl get mrds --show-labels
6
7# Verify CRD creation matches activation
8kubectl get crds | grep example.com | wc -l
9kubectl get mrds -l state=Active | wc -l

Relationship to other features

Provider capabilities integrate with:

  • MRDs - safe-start controls default activation state
  • Activation policies - Work together to control resource availability
  • Package manager - Crossplane reads capabilities during package installation
  • RBAC - Some capabilities require extra permissions
  • Compositions - May need updates when capabilities change resource availability

Capabilities provide a foundation for evolving provider behavior while maintaining compatibility with existing Crossplane installations.