flipt_client 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8cfa993fb8a7521e64c37cef82bf58088f8961d9779e6c5dc9092696a127c6ff
4
- data.tar.gz: 2cddbf45abafabd21660a60ab64378a2b1c4bfdafee4b931805ca8b2a1c2d002
3
+ metadata.gz: 2759b9ac786742b26aa0805c4d4861a1ccb9cb82c903a1bcab6c0ea3c446dfab
4
+ data.tar.gz: b1a8467e4bed68e87efef88a3228020e2600391d3f529ed2a10cc3abfc1b6b56
5
5
  SHA512:
6
- metadata.gz: b2cc595e3b40f37c420b920415d65e439a6295ddc1d1b4c22dc0fb2cb98e43e36912842568e1eb47246a088f15eb6bcce530e020daf0c2d34253fec9fa18347d
7
- data.tar.gz: 26c75eb569c0e0df06cf287ae7f9cb5beb0466be5e1c1cb8ec49252d38277914afa842f56650d7dd857cb3696d73d17a68ea6082ada6101f3bbfa729142c934f
6
+ metadata.gz: a818447135c3e62fe0bc0d4931225896778526df2f883f5484c61992f92de5366dff9186a277799a34be5bc75beb14ff2e9fa85fefdf393d848e50d5fc62eb9c
7
+ data.tar.gz: 76e27417733c3ce583316ac3cda586cd090dbcb824bdfa611335f4edc42b7b764e8ce1bf912bc5878db683bcfe81304f93771abd2ab1d590077c08551972980a
data/README.md CHANGED
@@ -114,6 +114,7 @@ The `Flipt::Client` constructor accepts the following keyword arguments:
114
114
  - `fetch_mode`: The fetch mode to use. Defaults to polling.
115
115
  - `error_strategy`: The error strategy to use. Defaults to fail. See [Error Strategies](#error-strategies).
116
116
  - `snapshot`: The snapshot to use when initializing the client. Defaults to no snapshot. See [Snapshotting](#snapshotting).
117
+ - `tls_config`: The TLS configuration for connecting to servers with custom certificates. See [TLS Configuration](#tls-configuration).
117
118
 
118
119
  ### Authentication
119
120
 
@@ -123,6 +124,126 @@ The `Flipt::Client` supports the following authentication strategies:
123
124
  - [Client Token Authentication](https://docs.flipt.io/authentication/using-tokens)
124
125
  - [JWT Authentication](https://docs.flipt.io/authentication/using-jwts)
125
126
 
127
+ ### TLS Configuration
128
+
129
+ The `Flipt::Client` supports configuring TLS settings for secure connections to Flipt servers. This is useful when:
130
+
131
+ - Connecting to Flipt servers with self-signed certificates
132
+ - Using custom Certificate Authorities (CAs)
133
+ - Implementing mutual TLS authentication
134
+ - Testing with insecure connections (development only)
135
+
136
+ #### Basic TLS with Custom CA Certificate
137
+
138
+ ```ruby
139
+ # Using a CA certificate file
140
+ tls_config = Flipt::TlsConfig.with_ca_cert_file('/path/to/ca.pem')
141
+
142
+ client = Flipt::Client.new(
143
+ url: 'https://flipt.example.com',
144
+ tls_config: tls_config
145
+ )
146
+ ```
147
+
148
+ ```ruby
149
+ # Using CA certificate data directly
150
+ ca_cert_data = File.read('/path/to/ca.pem')
151
+ tls_config = Flipt::TlsConfig.with_ca_cert_data(ca_cert_data)
152
+
153
+ client = Flipt::Client.new(
154
+ url: 'https://flipt.example.com',
155
+ tls_config: tls_config
156
+ )
157
+ ```
158
+
159
+ #### Mutual TLS Authentication
160
+
161
+ ```ruby
162
+ # Using certificate and key files
163
+ tls_config = Flipt::TlsConfig.with_mutual_tls('/path/to/client.pem', '/path/to/client.key')
164
+
165
+ client = Flipt::Client.new(
166
+ url: 'https://flipt.example.com',
167
+ tls_config: tls_config
168
+ )
169
+ ```
170
+
171
+ ```ruby
172
+ # Using certificate and key data directly
173
+ client_cert_data = File.read('/path/to/client.pem')
174
+ client_key_data = File.read('/path/to/client.key')
175
+
176
+ tls_config = Flipt::TlsConfig.with_mutual_tls_data(client_cert_data, client_key_data)
177
+
178
+ client = Flipt::Client.new(
179
+ url: 'https://flipt.example.com',
180
+ tls_config: tls_config
181
+ )
182
+ ```
183
+
184
+ #### Advanced TLS Configuration
185
+
186
+ ```ruby
187
+ # Full TLS configuration with all options
188
+ tls_config = Flipt::TlsConfig.new(
189
+ ca_cert_file: '/path/to/ca.pem',
190
+ client_cert_file: '/path/to/client.pem',
191
+ client_key_file: '/path/to/client.key',
192
+ insecure_skip_verify: false
193
+ )
194
+
195
+ client = Flipt::Client.new(
196
+ url: 'https://flipt.example.com',
197
+ tls_config: tls_config
198
+ )
199
+ ```
200
+
201
+ #### Development Mode (Insecure)
202
+
203
+ **⚠️ WARNING: Only use this in development environments!**
204
+
205
+ ```ruby
206
+ # Skip certificate verification (NOT for production)
207
+ tls_config = Flipt::TlsConfig.insecure
208
+
209
+ client = Flipt::Client.new(
210
+ url: 'https://localhost:8443',
211
+ tls_config: tls_config
212
+ )
213
+ ```
214
+
215
+ #### Self-Signed Certificates
216
+
217
+ For self-signed certificates where you need to skip hostname verification while still validating the certificate chain:
218
+
219
+ ```ruby
220
+ # Skip hostname verification for self-signed certificates
221
+ tls_config = Flipt::TlsConfig.new(
222
+ ca_cert_file: '/path/to/ca.pem',
223
+ insecure_skip_hostname_verify: true
224
+ )
225
+
226
+ client = Flipt::Client.new(
227
+ url: 'https://flipt.example.com',
228
+ tls_config: tls_config
229
+ )
230
+ ```
231
+
232
+ #### TLS Configuration Options
233
+
234
+ The `TlsConfig` class supports the following options:
235
+
236
+ - `ca_cert_file`: Path to custom CA certificate file (PEM format)
237
+ - `ca_cert_data`: Raw CA certificate content (PEM format) - takes precedence over `ca_cert_file`
238
+ - `insecure_skip_verify`: Skip certificate verification (development only)
239
+ - `insecure_skip_hostname_verify`: Skip hostname verification while maintaining certificate validation (development only)
240
+ - `client_cert_file`: Client certificate file for mutual TLS (PEM format)
241
+ - `client_key_file`: Client private key file for mutual TLS (PEM format)
242
+ - `client_cert_data`: Raw client certificate content (PEM format) - takes precedence over `client_cert_file`
243
+ - `client_key_data`: Raw client private key content (PEM format) - takes precedence over `client_key_file`
244
+
245
+ > **Note**: When both file paths and data are provided, the data fields take precedence. For example, if both `ca_cert_file` and `ca_cert_data` are set, `ca_cert_data` will be used.
246
+
126
247
  ### Error Strategies
127
248
 
128
249
  The client supports the following error strategies:
Binary file
Binary file
@@ -41,6 +41,112 @@ module Flipt
41
41
  end
42
42
  end
43
43
 
44
+ # TlsConfig provides configuration for TLS connections to Flipt servers
45
+ class TlsConfig
46
+ attr_reader :ca_cert_file, :ca_cert_data, :insecure_skip_verify, :insecure_skip_hostname_verify,
47
+ :client_cert_file, :client_key_file, :client_cert_data, :client_key_data
48
+
49
+ # Initialize TLS configuration
50
+ #
51
+ # @param ca_cert_file [String, nil] Path to CA certificate file (PEM format)
52
+ # @param ca_cert_data [String, nil] Raw CA certificate content (PEM format)
53
+ # @param insecure_skip_verify [Boolean, nil] Skip certificate verification (development only)
54
+ # @param insecure_skip_hostname_verify [Boolean, nil] Skip hostname verification
55
+ # while maintaining certificate validation (development only)
56
+ # @param client_cert_file [String, nil] Path to client certificate file (PEM format)
57
+ # @param client_key_file [String, nil] Path to client key file (PEM format)
58
+ # @param client_cert_data [String, nil] Raw client certificate content (PEM format)
59
+ # @param client_key_data [String, nil] Raw client key content (PEM format)
60
+ def initialize(ca_cert_file: nil, ca_cert_data: nil, insecure_skip_verify: nil,
61
+ insecure_skip_hostname_verify: nil, client_cert_file: nil, client_key_file: nil,
62
+ client_cert_data: nil, client_key_data: nil)
63
+ @ca_cert_file = ca_cert_file
64
+ @ca_cert_data = ca_cert_data
65
+ @insecure_skip_verify = insecure_skip_verify
66
+ @insecure_skip_hostname_verify = insecure_skip_hostname_verify
67
+ @client_cert_file = client_cert_file
68
+ @client_key_file = client_key_file
69
+ @client_cert_data = client_cert_data
70
+ @client_key_data = client_key_data
71
+
72
+ validate_files!
73
+ end
74
+
75
+ # Create TLS config for insecure connections (development only)
76
+ # WARNING: Only use this in development environments
77
+ #
78
+ # @return [TlsConfig] TLS config with certificate verification disabled
79
+ # @deprecated Use TlsConfig constructor instead
80
+ def self.insecure
81
+ new(insecure_skip_verify: true)
82
+ end
83
+
84
+ # Create TLS config with CA certificate file
85
+ #
86
+ # @param ca_cert_file [String] Path to CA certificate file
87
+ # @return [TlsConfig] TLS config with custom CA certificate
88
+ def self.with_ca_cert_file(ca_cert_file)
89
+ new(ca_cert_file: ca_cert_file)
90
+ end
91
+
92
+ # Create TLS config with CA certificate data
93
+ #
94
+ # @param ca_cert_data [String] CA certificate content in PEM format
95
+ # @return [TlsConfig] TLS config with custom CA certificate
96
+ def self.with_ca_cert_data(ca_cert_data)
97
+ new(ca_cert_data: ca_cert_data)
98
+ end
99
+
100
+ # Create TLS config for mutual TLS with certificate files
101
+ #
102
+ # @param client_cert_file [String] Path to client certificate file
103
+ # @param client_key_file [String] Path to client key file
104
+ # @return [TlsConfig] TLS config with mutual TLS
105
+ def self.with_mutual_tls(client_cert_file, client_key_file)
106
+ new(client_cert_file: client_cert_file, client_key_file: client_key_file)
107
+ end
108
+
109
+ # Create TLS config for mutual TLS with certificate data
110
+ #
111
+ # @param client_cert_data [String] Client certificate content in PEM format
112
+ # @param client_key_data [String] Client key content in PEM format
113
+ # @return [TlsConfig] TLS config with mutual TLS
114
+ def self.with_mutual_tls_data(client_cert_data, client_key_data)
115
+ new(client_cert_data: client_cert_data, client_key_data: client_key_data)
116
+ end
117
+
118
+ # Convert to hash for JSON serialization
119
+ # @return [Hash] TLS configuration as hash
120
+ def to_h
121
+ hash = {}
122
+ hash[:ca_cert_file] = @ca_cert_file if @ca_cert_file
123
+ hash[:ca_cert_data] = @ca_cert_data if @ca_cert_data
124
+ hash[:insecure_skip_verify] = @insecure_skip_verify unless @insecure_skip_verify.nil?
125
+ hash[:insecure_skip_hostname_verify] = @insecure_skip_hostname_verify unless @insecure_skip_hostname_verify.nil?
126
+ hash[:client_cert_file] = @client_cert_file if @client_cert_file
127
+ hash[:client_key_file] = @client_key_file if @client_key_file
128
+ hash[:client_cert_data] = @client_cert_data if @client_cert_data
129
+ hash[:client_key_data] = @client_key_data if @client_key_data
130
+ hash
131
+ end
132
+
133
+ private
134
+
135
+ def validate_files!
136
+ validate_file_exists(@ca_cert_file, 'CA certificate file') if @ca_cert_file
137
+ validate_file_exists(@client_cert_file, 'Client certificate file') if @client_cert_file
138
+ validate_file_exists(@client_key_file, 'Client key file') if @client_key_file
139
+ end
140
+
141
+ def validate_file_exists(file_path, description)
142
+ return if file_path.nil? || file_path.strip.empty?
143
+
144
+ return if File.exist?(file_path)
145
+
146
+ raise ValidationError, "#{description} does not exist: #{file_path}"
147
+ end
148
+ end
149
+
44
150
  # VariantEvaluationResponse
45
151
  # @attr_reader [String] flag_key
46
152
  # @attr_reader [Boolean] match
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Flipt
4
- VERSION = '1.0.0'
4
+ VERSION = '1.2.0'
5
5
  end
data/lib/flipt_client.rb CHANGED
@@ -65,12 +65,14 @@ module Flipt
65
65
  # Note: Streaming is currently only supported when using the SDK with Flipt Cloud or Flipt v2.
66
66
  # @option opts [Symbol] :error_strategy error strategy to use for the client (:fail or :fallback).
67
67
  # @option opts [String] :snapshot snapshot to use when initializing the client
68
+ # @option opts [TlsConfig] :tls_config TLS configuration for connecting to servers with custom certificates
68
69
  def initialize(**opts)
69
70
  @namespace = opts.fetch(:namespace, 'default')
70
71
 
71
72
  opts[:authentication] = validate_authentication(opts.fetch(:authentication, NoAuthentication.new))
72
73
  opts[:fetch_mode] = validate_fetch_mode(opts.fetch(:fetch_mode, :polling))
73
74
  opts[:error_strategy] = validate_error_strategy(opts.fetch(:error_strategy, :fail))
75
+ opts[:tls_config] = validate_tls_config(opts.fetch(:tls_config, nil))
74
76
 
75
77
  @engine = self.class.initialize_engine(opts.to_json)
76
78
  ObjectSpace.define_finalizer(self, self.class.finalize(@engine))
@@ -223,6 +225,13 @@ module Flipt
223
225
 
224
226
  raise ValidationError, 'invalid error strategy'
225
227
  end
228
+
229
+ def validate_tls_config(tls_config)
230
+ return nil if tls_config.nil?
231
+ return tls_config.to_h if tls_config.is_a?(TlsConfig)
232
+
233
+ raise ValidationError, 'invalid tls_config: must be TlsConfig instance'
234
+ end
226
235
  end
227
236
 
228
237
  # Deprecation shim for EvaluationClient
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flipt_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Flipt Devs
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-06-09 00:00:00.000000000 Z
11
+ date: 2025-07-11 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Flipt Client Evaluation SDK
14
14
  email: