A Kubernetes operator that bridges Hardware Security Module (HSM) data storage with Kubernetes Secrets, providing true secret portability th
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 251 lines 8.0 kB view raw
1/* 2Copyright 2025. 3 4Licensed under the Apache License, Version 2.0 (the "License"); 5you may not use this file except in compliance with the License. 6You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10Unless required by applicable law or agreed to in writing, software 11distributed under the License is distributed on an "AS IS" BASIS, 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13See the License for the specific language governing permissions and 14limitations under the License. 15*/ 16 17package api 18 19import ( 20 "time" 21 22 "github.com/evanjarrett/hsm-secrets-operator/internal/hsm" 23) 24 25// SecretFormat defines the format of the secret data 26type SecretFormat string 27 28const ( 29 // SecretFormatJSON stores data as JSON key-value pairs 30 SecretFormatJSON SecretFormat = "json" 31 // SecretFormatBinary stores raw binary data 32 SecretFormatBinary SecretFormat = "binary" 33 // SecretFormatText stores plain text data 34 SecretFormatText SecretFormat = "text" 35) 36 37// CreateSecretRequest represents a request to create a new secret 38type CreateSecretRequest struct { 39 // Label is the human-readable identifier for the secret 40 Label string `json:"label" validate:"required,min=1,max=255"` 41 42 // ID is the unique numeric identifier for the secret on the HSM 43 ID uint32 `json:"id" validate:"required,min=1"` 44 45 // Format specifies how the data should be stored 46 Format SecretFormat `json:"format" validate:"required,oneof=json binary text"` 47 48 // Data contains the actual secret data 49 Data map[string]any `json:"data" validate:"required"` 50 51 // Description is an optional description of the secret 52 Description string `json:"description,omitempty" validate:"max=1000"` 53 54 // Tags are optional metadata tags 55 Tags map[string]string `json:"tags,omitempty"` 56} 57 58// UpdateSecretRequest represents a request to update an existing secret 59type UpdateSecretRequest struct { 60 // Data contains the updated secret data 61 Data map[string]any `json:"data" validate:"required"` 62 63 // Description is an optional updated description 64 Description string `json:"description,omitempty" validate:"max=1000"` 65 66 // Tags are optional updated metadata tags 67 Tags map[string]string `json:"tags,omitempty"` 68} 69 70// ImportSecretRequest represents a request to import a secret from external source 71type ImportSecretRequest struct { 72 // Source specifies where to import from (kubernetes, vault, etc.) 73 Source string `json:"source" validate:"required,oneof=kubernetes vault file"` 74 75 // SecretName is the name of the source secret 76 SecretName string `json:"secret_name" validate:"required"` 77 78 // SecretNamespace is the namespace for Kubernetes secrets 79 SecretNamespace string `json:"secret_namespace,omitempty"` 80 81 // TargetLabel is the label for the imported secret on HSM 82 TargetLabel string `json:"target_label" validate:"required,min=1,max=255"` 83 84 // TargetID is the ID for the imported secret on HSM 85 TargetID uint32 `json:"target_id" validate:"required,min=1"` 86 87 // Format specifies how the imported data should be stored 88 Format SecretFormat `json:"format" validate:"required,oneof=json binary text"` 89 90 // KeyMapping maps source keys to target keys (optional) 91 KeyMapping map[string]string `json:"key_mapping,omitempty"` 92} 93 94// SecretInfo represents information about a secret 95type SecretInfo struct { 96 // Label is the human-readable identifier 97 Label string `json:"label"` 98 99 // ID is the unique numeric identifier on the HSM 100 ID uint32 `json:"id"` 101 102 // Format specifies the data format 103 Format SecretFormat `json:"format"` 104 105 // Description is the secret description 106 Description string `json:"description,omitempty"` 107 108 // Tags are metadata tags 109 Tags map[string]string `json:"tags,omitempty"` 110 111 // CreatedAt is when the secret was created 112 CreatedAt time.Time `json:"created_at"` 113 114 // UpdatedAt is when the secret was last updated 115 UpdatedAt time.Time `json:"updated_at"` 116 117 // Size is the size of the secret data in bytes 118 Size int64 `json:"size"` 119 120 // Checksum is the SHA256 checksum of the data 121 Checksum string `json:"checksum"` 122 123 // IsReplicated indicates if the secret is replicated across nodes 124 IsReplicated bool `json:"is_replicated"` 125} 126 127// SecretData represents the actual secret data 128type SecretData struct { 129 // Data contains the secret key-value pairs 130 Data map[string]any `json:"data"` 131 132 // Metadata contains additional information about the secret 133 Metadata SecretInfo `json:"metadata"` 134} 135 136// SecretList represents a list of secrets 137type SecretList struct { 138 // Secrets is the list of secret information 139 Secrets []SecretInfo `json:"secrets"` 140 141 // Total is the total number of secrets 142 Total int `json:"total"` 143 144 // Page is the current page number (for pagination) 145 Page int `json:"page,omitempty"` 146 147 // PageSize is the number of items per page 148 PageSize int `json:"page_size,omitempty"` 149} 150 151// APIResponse represents a standard API response 152type APIResponse struct { 153 // Success indicates if the operation was successful 154 Success bool `json:"success"` 155 156 // Message provides additional information about the result 157 Message string `json:"message,omitempty"` 158 159 // Data contains the response data 160 Data any `json:"data,omitempty"` 161 162 // Error contains error details if the operation failed 163 Error *APIError `json:"error,omitempty"` 164} 165 166// APIError represents an API error 167type APIError struct { 168 // Code is the error code 169 Code string `json:"code"` 170 171 // Message is the human-readable error message 172 Message string `json:"message"` 173 174 // Details contains additional error details 175 Details map[string]any `json:"details,omitempty"` 176} 177 178// HealthStatus represents the health status of the API server 179type HealthStatus struct { 180 // Status is the overall health status 181 Status string `json:"status"` 182 183 // HSMConnected indicates if HSM is connected 184 HSMConnected bool `json:"hsm_connected"` 185 186 // ReplicationEnabled indicates if replication is enabled 187 ReplicationEnabled bool `json:"replication_enabled"` 188 189 // ActiveNodes is the number of active HSM nodes 190 ActiveNodes int `json:"active_nodes"` 191 192 // Timestamp is when the health check was performed 193 Timestamp time.Time `json:"timestamp"` 194} 195 196// ListSecretsResponse represents the response for listing secrets 197type ListSecretsResponse struct { 198 Secrets []string `json:"secrets"` 199 Count int `json:"count"` 200 Prefix string `json:"prefix,omitempty"` 201} 202 203// ReadSecretResponse represents the response for reading a secret 204type ReadSecretResponse struct { 205 Path string `json:"path"` 206 Data map[string][]byte `json:"data"` 207 Checksum string `json:"checksum,omitempty"` 208 DeviceCount int `json:"deviceCount,omitempty"` 209} 210 211// WriteSecretResponse represents the response for writing a secret 212type WriteSecretResponse struct { 213 Path string `json:"path"` 214 Keys int `json:"keys"` 215} 216 217// DeleteSecretResponse represents the response for deleting a secret 218type DeleteSecretResponse struct { 219 Path string `json:"path"` 220 Devices int `json:"devices"` 221 DeviceResults map[string]any `json:"deviceResults"` 222 Warnings []string `json:"warnings,omitempty"` 223} 224 225// ReadMetadataResponse represents the response for reading metadata 226type ReadMetadataResponse struct { 227 Path string `json:"path"` 228 Metadata *hsm.SecretMetadata `json:"metadata"` 229} 230 231// GetChecksumResponse represents the response for getting a checksum 232type GetChecksumResponse struct { 233 Path string `json:"path"` 234 Checksum string `json:"checksum"` 235} 236 237type IsConnectedResponse struct { 238 Devices map[string]bool `json:"devices"` 239 TotalDevices int `json:"totalDevices"` 240} 241 242// GetInfoResponse represents the response for getting HSM info 243type GetInfoResponse struct { 244 DeviceInfos map[string]*hsm.HSMInfo `json:"deviceInfos"` // deviceName -> HSMInfo 245} 246 247// ChangePINRequest represents a request to change HSM PIN 248type ChangePINRequest struct { 249 OldPIN string `json:"old_pin" validate:"required"` 250 NewPIN string `json:"new_pin" validate:"required"` 251}