# Ruby SDK

<figure><img src="https://859776093-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPL6k1aGsLiFiiJ3Y7zCl%2Fuploads%2FxHW0mOx92KuBud8H8oLE%2Fimage.png?alt=media&#x26;token=14cb111c-05bf-4971-ab3d-072976523510" alt=""><figcaption></figcaption></figure>

## ダウンロードとインストール

### インストール

Ruby SDKでは、Ruby 3.1以降がサポートされています。詳細については[こちらのウェブサイト](https://rubygems.org/gems/keeper_secrets_manager)をご参照ください。

#### gemを使用してインストールする場合

```
gem install keeper_secrets_manager -v 17.1.0
```

#### Gemfileに追加する場合

```bash
gem 'keeper_secrets_manager', '~> 17.1'
```

次に以下を実行します。

```
bundle install
```

### ソースコード

Rubyのソースコードは[GitHubリポジトリ](https://github.com/Keeper-Security/secrets-manager/tree/master/sdk/ruby)で公開されています。

## SDKの使用

### ストレージの初期化

KeeperシークレットマネージャーSDKでは、クライアントデバイス上にストレージを初期化するためにワンタイムアクセストークンが必要です。初期化後は、SDKが構成を保存し、以降の利用時に再読み込みします。

{% code overflow="wrap" %}

```ruby
KeeperSecretsManager.new(token: token, config: storage, hostname: hostname, verify_ssl_certs: verify_ssl_certs)
```

{% endcode %}

| パラメータ              | 型                 | 必須 | デフォルト                  | 説明                                             |
| ------------------ | ----------------- | -- | ---------------------- | ---------------------------------------------- |
| `token`            | `String`          | 任意 | `nil`                  | 初期バインディングに使用するワンタイムアクセストークン                    |
| `config`           | `KeyValueStorage` | 必須 | なし                     | 構成を永続化するためのストレージ実装                             |
| `hostname`         | `String`          | 任意 | `'keepersecurity.com'` | APIホスト名 (例: EUデータセンターの場合は 'keepersecurity.eu') |
| `verify_ssl_certs` | `Boolean`         | 任意 | `true`                 | SSL証明書検証の有効/無効の設定                              |

{% hint style="info" %}
ワンタイムアクセストークンを使用する場合、トークンを紐付けて構成を完全に取得するために**最低1つの読み取り操作**が必要です。
{% endhint %}

### 使用例

#### ワンタイムアクセストークンを使用する場合

```ruby
require 'keeper_secrets_manager'

token = "US:ONE_TIME_TOKEN_HERE"

# 初回セットアップ - トークンの紐付け
storage = KeeperSecretsManager::Storage::FileStorage.new('keeper_config.json')
secrets_manager = KeeperSecretsManager.new(token: token, config: storage)

# 少なくとも1回の操作が必要（構成の取得）
records = secrets_manager.get_secrets

# 構成ファイルが保存されたことを確認
File.exist?('keeper_config.json')  # true を返す
```

#### ファイルベースのストレージを使用する場合

アプリケーション再起動後も構成を永続的に保持する場合

```ruby
require 'keeper_secrets_manager'

# 初回の紐付け後、構成ファイルから読み込む
secrets_manager = KeeperSecretsManager.from_file('keeper_config.json')
```

ボルトで生成されたBase64構成ファイルを使用する場合

```ruby
require 'keeper_secrets_manager'

base64_config = File.read('config.base64').strip
storage = KeeperSecretsManager::Storage::InMemoryStorage.new(base64_config)
secrets_manager = KeeperSecretsManager.new(config: storage)
```

#### 環境変数を使用する場合

環境変数から読み取り専用の構成をロードする方法

```ruby
require 'keeper_secrets_manager'

# 事前に環境変数を設定:
# export KSM_HOSTNAME=keepersecurity.com
# export KSM_CLIENT_ID=your-client-id
# export KSM_PRIVATE_KEY=your-private-key
# export KSM_APP_KEY=your-app-key
# export KSM_SERVER_PUBLIC_KEY_ID=10

# 環境変数から構成をロード
config = KeeperSecretsManager::Storage::EnvironmentStorage.new('KSM_')
secrets_manager = KeeperSecretsManager.new(config: config)
```

## シークレットの取得

### シークレットの取得

```ruby
get_secrets(uids = [])
```

| パラメータ  | 型               | 必須 | デフォルト | 説明                                      |
| ------ | --------------- | -- | ----- | --------------------------------------- |
| `uids` | `Array<String>` | 任意 | `[]`  | 取得対象のレコードUID一覧。空配列の場合はすべてのシークレットを取得します。 |

### レスポンス

**型:** `Array<KeeperRecord>`

すべてのKeeperレコード、または指定したUIDに一致するレコードの配列が返されます。

### 使用例

すべてのシークレットを取得する

```ruby
require 'keeper_secrets_manager'

secrets_manager = KeeperSecretsManager.from_file('keeper_config.json')

# すべてのシークレットを取得
records = secrets_manager.get_secrets

records.each do |record|
  puts "#{record.title} (#{record.type})"
end
```

UIDを指定して取得する

```ruby
# 単一レコードをUIDで取得
records = secrets_manager.get_secrets(['RECORD_UID'])
record = records.first

# 複数UIDを指定して取得
uids = ['UID1', 'UID2', 'UID3']
records = secrets_manager.get_secrets(uids)
```

#### タイトルでシークレットを取得する

```ruby
# タイトルに一致するすべてのシークレットを取得
get_secrets_by_title(title)

# タイトルに一致する最初のシークレットを取得
get_secret_by_title(title)
```

| パラメータ   | 型        | 必須 | デフォルト | 説明                   |
| ------- | -------- | -- | ----- | -------------------- |
| `title` | `String` | 必須 | なし    | 検索対象のレコードタイトル (完全一致) |

#### レスポンス

* `get_secrets_by_title` → `Array<KeeperRecord>`
* `get_secret_by_title` → `KeeperRecord`

同じタイトルに一致するすべてのレコード、または最初に一致したレコードを返します。

#### 使用例

```ruby
require 'keeper_secrets_manager'

secrets_manager = KeeperSecretsManager.from_file('keeper_config.json')

# タイトルが完全一致するシークレットを1件取得
record = secrets_manager.get_secret_by_title('My Database Credentials')

# 同じタイトルを持つ複数レコードを取得
records = secrets_manager.get_secrets_by_title('My Login')

# レコードからフィールドにアクセス
puts "Login: #{record.login}"
puts "Password: #{record.password}"
```

## シークレットから値を取得する

シークレットを取得した後、フィールド値には複数の方法でアクセスできます。

#### 動的フィールドアクセスを使用する方法

```ruby
record = secrets_manager.get_secrets(['RECORD_UID']).first

# 標準フィールドに動的にアクセス
login = record.login
password = record.password
url = record.url

# 複合フィールドにアクセス
host = record.host  # hostName と port を含むハッシュが返る
```

#### 明示的なフィールドメソッドを使用する方法

```ruby
# 単一値の取得（最初の値を返す）
login = record.get_field_value_single('login')

# 複数値の取得（配列を返す）
passwords = record.get_field_value('password')

# ラベル付きカスタムフィールドへのアクセス
api_key = record.get_field_value_single('API Key')
environment = record.get_field_value_single('Environment')
```

#### Keeper表記法を使用する方法

```ruby
# URI形式のNotationを使ってフィールドにアクセス
password = secrets_manager.get_notation("keeper://#{record.uid}/field/password")

# レコードタイトルを使ってアクセス
url = secrets_manager.get_notation("keeper://My Login/field/url")

# 複合フィールドのプロパティにアクセス
hostname = secrets_manager.get_notation("keeper://#{record.uid}/field/host[hostName]")
port = secrets_manager.get_notation("keeper://#{record.uid}/field/host[port]")

# カスタムフィールドへアクセス
env = secrets_manager.get_notation("keeper://#{record.uid}/custom_field/Environment")
```

## TOTPコードの取得

TOTPコードを生成するには、まずレコードからTOTP URLを取得し、`KeeperSecretsManager::TOTP` モジュールを使用します。

```ruby
# レコードからTOTP URLを取得
totp_url = record.get_field_value_single('oneTimeCode')

# パースしてコードを生成
require 'keeper_secrets_manager/totp'
totp_params = KeeperSecretsManager::TOTP.parse_url(totp_url)
totp_code = KeeperSecretsManager::TOTP.generate_code(
  totp_params['secret'],
  algorithm: totp_params['algorithm'],
  digits: totp_params['digits'],
  period: totp_params['period']
)
```

| パラメータ       | 型         | 必須 | デフォルト    | 説明                                       |
| ----------- | --------- | -- | -------- | ---------------------------------------- |
| `secret`    | `String`  | 必須 | なし       | Base32形式でエンコードされたTOTPシークレット              |
| `algorithm` | `String`  | 任意 | `'SHA1'` | 使用するハッシュアルゴリズム 　(SHA1 / SHA256 / SHA512) |
| `digits`    | `Integer` | 任意 | `6`      | 生成するコードの桁数                               |
| `period`    | `Integer` | 任意 | `30`     | コードの有効期間 (秒)                             |

#### レスポンス

**型:** `String`

2要素認証に使用する現在のTOTP (Time-Based One-Time Password) コードが返されます。

#### 使用例

```ruby
require 'keeper_secrets_manager'

secrets_manager = KeeperSecretsManager.from_file('keeper_config.json')

# TOTPを含むレコードを取得
record = secrets_manager.get_secrets(['RECORD_UID']).first

# レコードからTOTP URLを取得
totp_url = record.get_field_value_single('oneTimeCode')

# TOTPパラメータをパース
require 'keeper_secrets_manager/totp'
totp_params = KeeperSecretsManager::TOTP.parse_url(totp_url)

# TOTPコードを生成
totp_code = KeeperSecretsManager::TOTP.generate_code(
  totp_params['secret'],
  algorithm: totp_params['algorithm'],
  digits: totp_params['digits'],
  period: totp_params['period']
)

puts "Current TOTP code: #{totp_code}"
puts "Expires in: #{30 - (Time.now.to_i % 30)} seconds"
```

{% hint style="info" %}
TOTPコードの生成には、Base32デコード用の **base32** gem が必要です。
{% endhint %}

インストール方法

```
gem install base32
```

## ランダムパスワードの生成

暗号学的に安全なランダムパスワードを生成できます。文字種や長さなどを柔軟に指定でき、シークレットをプログラムから作成または更新する際に便利です。

```ruby
KeeperSecretsManager::Utils.generate_password(
  length: 64,
  lowercase: 0,
  uppercase: 0,
  digits: 0,
  special_characters: 0
)
```

| パラメータ                | 型         | 必須 | デフォルト | 説明                                     |
| -------------------- | --------- | -- | ----- | -------------------------------------- |
| `length`             | `Integer` | 任意 | `64`  | パスワード全体の長さ                             |
| `lowercase`          | `Integer` | 任意 | `0`   | 使用する小文字　(a–z) の最小数                     |
| `uppercase`          | `Integer` | 任意 | `0`   | 使用する大文字 (A–Z) の最小数                     |
| `digits`             | `Integer` | 任意 | `0`   | 使用する数字 (0–9) の最小数                      |
| `special_characters` | `Integer` | 任意 | `0`   | 使用する記号 (!@#$%^&\*()\_+-=\[]{} など) の最小数 |

#### レスポンス

**型:** `String`

指定した要件を満たす、暗号学的に安全なランダムパスワードを返します。

{% hint style="info" %}
この関数は、暗号学的に安全な乱数生成を行うRubyの `SecureRandom` を使用しており、適切な文字分布を確保するためにFisher–Yatesシャッフルを適用します。
{% endhint %}

### 使用例

#### デフォルト設定で64文字のパスワードを生成

```ruby
require 'keeper_secrets_manager'

# すべてデフォルト値で生成（64文字のランダムパスワード）
password = KeeperSecretsManager::Utils.generate_password
puts "Generated: #{password}"
# => "Xk9$mP2..."  (64 characters)
```

#### 生成要件を指定する例

```ruby
# 32文字で、各文字種の最低数を指定
password = KeeperSecretsManager::Utils.generate_password(
  length: 32,
  lowercase: 2,
  uppercase: 2,
  digits: 2,
  special_characters: 2
)

puts "Generated: #{password}"
# => "aB12$xY34..."  (32文字、各文字種を最低2つずつ含む)

# 様々な要件で強度の高いパスワードを生成
password = KeeperSecretsManager::Utils.generate_password(
  length: 20,
  lowercase: 3,
  uppercase: 3,
  digits: 3,
  special_characters: 3
)
```

#### 新しいシークレットを作成する際に使用する例

```ruby
require 'keeper_secrets_manager'

secrets_manager = KeeperSecretsManager.from_file('keeper_config.json')

# 生成したパスワードを使って新しいログインレコードを作成
record_data = {
  type: 'login',
  title: 'Production Database',
  fields: [
    { type: 'login', value: ['db_admin'] },
    {
      type: 'password',
      value: [KeeperSecretsManager::Utils.generate_password(
        length: 32,
        lowercase: 4,
        uppercase: 4,
        digits: 4,
        special_characters: 4
      )]
    },
    { type: 'url', value: ['https://db.example.com'] }
  ],
  notes: 'Auto-generated secure password'
}

# 必須のフォルダUIDを指定
options = KeeperSecretsManager::Dto::CreateOptions.new(folder_uid: 'FOLDER_UID')
record_uid = secrets_manager.create_secret(record_data, options)

puts "Created record with secure password: #{record_uid}"
```

#### 既存のシークレットを更新する際に使用する例

```ruby
require 'keeper_secrets_manager'

secrets_manager = KeeperSecretsManager.from_file('keeper_config.json')

# 既存レコードを取得
record = secrets_manager.get_secrets(['RECORD_UID']).first

# 新しいパスワードを生成して設定
new_password = KeeperSecretsManager::Utils.generate_password(
  length: 40,
  lowercase: 5,
  uppercase: 5,
  digits: 5,
  special_characters: 5
)

record.password = new_password

# 変更を保存
secrets_manager.update_secret(record)

puts "Password updated with new secure value"
```

#### パスワードローテーションスクリプト例

```ruby
require 'keeper_secrets_manager'

secrets_manager = KeeperSecretsManager.from_file('keeper_config.json')

# 複数レコードのパスワードをローテーション
record_uids = ['UID1', 'UID2', 'UID3']

record_uids.each do |uid|
  record = secrets_manager.get_secrets([uid]).first

  # 新しいパスワードを生成
  new_password = KeeperSecretsManager::Utils.generate_password(
    length: 32,
    lowercase: 3,
    uppercase: 3,
    digits: 3,
    special_characters: 3
  )

  # レコードを更新
  record.password = new_password
  record.notes = "Password rotated on #{Time.now}"

  secrets_manager.update_secret(record)

  puts "✓ Rotated password for: #{record.title}"
end
```

## シークレットの更新

```
update_secret(record)
```

| パラメータ    | 型              | 必須 | デフォルト | 説明                  |
| -------- | -------------- | -- | ----- | ------------------- |
| `record` | `KeeperRecord` | はい | なし    | ボルト内で更新する、変更済みのレコード |

### レスポンス

**型:** `void`

変更された値を使って、ボルト内のシークレットが更新されます。

### 使用例

```ruby
require 'keeper_secrets_manager'

secrets_manager = KeeperSecretsManager.from_file('keeper_config.json')

# 既存レコードを取得
record = secrets_manager.get_secrets(['RECORD_UID']).first

# 動的アクセスでフィールドを更新
record.password = 'NewSecurePassword123!'

# 明示的メソッドでフィールドを更新
record.set_field('login', 'new_username@example.com')

# ノートを更新
record.notes = "Updated on #{Time.now}"

# 変更を保存
secrets_manager.update_secret(record)

puts "Secret updated successfully"
```

## ファイルのダウンロード

```
download_file(file)
```

| パラメータ  | 型            | 必須 | デフォルト | 説明                                  |
| ------ | ------------ | -- | ----- | ----------------------------------- |
| `file` | `KeeperFile` | 必須 | なし    | ダウンロード対象となるKeeperRecord内のファイルオブジェクト |

### レスポンス

**型:** `Hash`

以下の情報を含むハッシュを返します。

* `'name'` — ファイル名
* `'data'` — バイナリ文字列としてのファイルデータ
* `'size'` — ファイルサイズ（バイト単位）
* `'type'` — ファイルのMIMEタイプ

### 使用例

```ruby
require 'keeper_secrets_manager'

secrets_manager = KeeperSecretsManager.from_file('keeper_config.json')

# ファイルを含むレコードを取得
record = secrets_manager.get_secrets(['RECORD_UID']).first

# レコードにファイルがあるか確認
if record.files && record.files.any?
  # 最初のファイルをダウンロード
  file = record.files.first
  downloaded = secrets_manager.download_file(file)

  # ディスクに保存
  filename = downloaded['name'] || 'downloaded_file'
  File.write(filename, downloaded['data'])

  puts "Downloaded: #{filename}"
  puts "Size: #{downloaded['size']} bytes"
  puts "Type: #{downloaded['type']}"
end
```

## ファイルのアップロード

```ruby
upload_file(owner_record_uid, file_data, file_name, file_title = nil)
```

| パラメータ              | 型        | 必須 | デフォルト | 説明                    |
| ------------------ | -------- | -- | ----- | --------------------- |
| `owner_record_uid` | `String` | 必須 | なし    | ファイルを添付する対象レコードのUID   |
| `file_data`        | `String` | 必須 | なし    | ファイル内容 (バイナリまたはテキスト)  |
| `file_name`        | `String` | 必須 | なし    | Keeper上でのファイル名        |
| `file_title`       | `String` | 任意 | nil   | Keeper上でのファイルのタイトル/説明 |

### レスポンス

**型:** `String`

アップロードされたファイルのUIDを返します。

### 使用例

```ruby
require 'keeper_secrets_manager'

secrets_manager = KeeperSecretsManager.from_file('keeper_config.json')

# ファイルをアップロード
file_uid = secrets_manager.upload_file(
  'RECORD_UID',                          # owner_record_uid
  File.read('/path/to/certificate.pem'), # file_data
  'certificate.pem',                     # file_name
  'Server Certificate'                   # file_title (任意)
)

puts "File uploaded with UID: #{file_uid}"

# テキストデータをアップロード
file_uid = secrets_manager.upload_file(
  'RECORD_UID',
  "server=localhost\nport=5432\n",
  'config.txt',
  'Database Config'
)
```

## シークレットの作成

```ruby
create_secret(record_data, options = nil)
```

| パラメータ         | 型               | 必須 | デフォルト | 説明                                              |
| ------------- | --------------- | -- | ----- | ----------------------------------------------- |
| `record_data` | `Hash`          | 必須 | なし    | レコード構造 (type、title、fields、custom、notes) を含むハッシュ |
| `options`     | `CreateOptions` | 必須 | なし    | folder\_uid (必須) と任意設定を含むCreateOptionsオブジェクト    |

### レスポンス

**型:** `String`

作成されたシークレットのUIDを返します。

### 要件

* 共有フォルダUID (folder\_uid) を指定する場合、そのUIDが必要
* 共有フォルダがシークレットマネージャーアプリケーションからアクセス可能であること
* あなた自身とシークレットマネージャーアプリケーションの両方に編集権限があること
* 共有フォルダ内に少なくとも1件のレコードが存在すること
* レコードのフィールド形式が正しく構成されていること (フィールドタイプの仕様を参照)

### 使用例

```ruby
require 'keeper_secrets_manager'

secrets_manager = KeeperSecretsManager.from_file('keeper_config.json')

# ログインレコードを新規作成
record_data = {
  type: 'login',
  title: 'Production Database',
  fields: [
    { type: 'login', value: ['db_admin'] },
    { type: 'password', value: ['SecurePassword123!'] },
    { type: 'url', value: ['https://db.example.com'] },
    {
      type: 'host',
      value: [{ hostName: '192.168.1.100', port: '5432' }],
      label: 'Database Host'
    }
  ],
  custom: [
    { type: 'text', label: 'Environment', value: ['Production'] },
    { type: 'text', label: 'Database Name', value: ['main_db'] }
  ],
  notes: 'Production database credentials'
}

# 必須のfolder_uidを指定してオプションを作成
options = KeeperSecretsManager::Dto::CreateOptions.new(folder_uid: 'FOLDER_UID')

# シークレットを作成
record_uid = secrets_manager.create_secret(record_data, options)

puts "Secret created with UID: #{record_uid}"

# 別の記述方法（オプションをインラインで渡す）
record_uid = secrets_manager.create_secret(
  record_data,
  KeeperSecretsManager::Dto::CreateOptions.new(folder_uid: 'FOLDER_UID')
)
```

#### カスタムタイプレコードの作成例

```ruby
# データベース認証情報レコードを作成
record_data = {
  type: 'databaseCredentials',
  title: 'MySQL Production',
  fields: [
    { type: 'text', label: 'Database Type', value: ['MySQL'] },
    {
      type: 'host',
      value: [{ hostName: 'mysql.example.com', port: '3306' }]
    },
    { type: 'login', value: ['root'] },
    { type: 'password', value: ['SecurePassword123!'] }
  ],
  notes: 'MySQL production database'
}

# 必須のfolder_uidを指定してオプションを作成
options = KeeperSecretsManager::Dto::CreateOptions.new(folder_uid: 'FOLDER_UID')
record_uid = secrets_manager.create_secret(record_data, options)
```

## シークレットの削除

```ruby
delete_secret(uids)
```

| パラメータ  | 型                            | 必須 | デフォルト | 説明                   |
| ------ | ---------------------------- | -- | ----- | -------------------- |
| `uids` | `String` または `Array<String>` | 必須 | なし    | 削除対象のレコードUID (複数指定可) |

### レスポンス

**型**: `void`

指定したシークレットをボルトから削除します。

### 使用例

```ruby
require 'keeper_secrets_manager'

secrets_manager = KeeperSecretsManager.from_file('keeper_config.json')

# 単一のシークレットを削除
secrets_manager.delete_secret('RECORD_UID')
puts "Secret deleted successfully"

# 複数のシークレットを削除
uids = ['UID1', 'UID2', 'UID3']
secrets_manager.delete_secret(uids)
puts "#{uids.length} secrets deleted"
```

## フォルダ

Ruby SDKでは、フォルダ操作に対して完全なCRUD (作成・取得・更新・削除) が利用できます。

## フォルダの取得

```ruby
get_folders
```

### レスポンス

**型**: `Array<KeeperFolder>`

シークレットマネージャーアプリケーションがアクセス可能なすべてのフォルダを返します。

### 使用例

```ruby
require 'keeper_secrets_manager'

secrets_manager = KeeperSecretsManager.from_file('keeper_config.json')

# すべてのフォルダを取得
folders = secrets_manager.get_folders

folders.each do |folder|
  puts "#{folder.name} (UID: #{folder.uid})"
end
```

## フォルダパスの取得

```
get_folder_path(folder_uid)
```

| パラメータ        | 型        | 必須 | デフォルト | 説明                |
| ------------ | -------- | -- | ----- | ----------------- |
| `folder_uid` | `String` | 必須 | なし    | パスを取得する対象フォルダのUID |

### レスポンス

型: `String`

フォルダの完全なパス（"/" 区切りのパンくずリスト形式）を返します。

### 使用例

```ruby
# フォルダのパス（パンくずリスト形式）を取得
path = secrets_manager.get_folder_path('FOLDER_UID')
puts "Folder path: #{path}"  # "Parent/Child/Grandchild"（例: 親/子/孫フォルダのパス）
```

## 名前でフォルダを検索

```ruby
find_folder_by_name(name, parent_uid: nil)
```

| パラメータ        | 型        | 必須 | デフォルト | 説明                      |
| ------------ | -------- | -- | ----- | ----------------------- |
| `name`       | `String` | 必須 | なし    | 検索するフォルダ名               |
| `parent_uid` | `String` | 任意 | `nil` | 指定した親フォルダ内を対象に検索する場合に指定 |

### レスポンス

**型**: `KeeperFolder` または `nil`

最初に一致したフォルダ、または一致しない場合は nil を返します。

### 使用例

```ruby
# 名前でフォルダを検索
folder = secrets_manager.find_folder_by_name('Finance')

# 特定の親フォルダ内でフォルダを検索
folder = secrets_manager.find_folder_by_name('Reports', parent_uid: 'PARENT_UID')
```

### フォルダツリーの構築

```ruby
# フォルダマネージャーの取得
fm = secrets_manager.folder_manager

# フォルダツリー全体を構築
tree = fm.build_folder_tree

# ツリー構造をコンソールに出力
fm.print_tree

# フォルダ関係を取得
ancestors = fm.get_ancestors('FOLDER_UID')      # [parent, grandparent, ...]
descendants = fm.get_descendants('FOLDER_UID')  # [children, grandchildren, ...]
```

## フォルダの作成

```
create_folder(name, parent_uid:)
```

| パラメータ       | 型      | 必須 | デフォルト | 説明                 |
| ----------- | ------ | -- | ----- | ------------------ |
| name        | String | 必須 | -     | 作成するフォルダ名          |
| parent\_uid | String | 必須 | -     | フォルダを配置する親フォルダのUID |

### レスポンス

**型:** `String`

作成されたフォルダのUIDを返します。

### 使用例

```ruby
require 'keeper_secrets_manager'

secrets_manager = KeeperSecretsManager.from_file('keeper_config.json')

# ルート階層（共有フォルダ内）にフォルダを作成
folder_uid = secrets_manager.create_folder('New Folder', parent_uid: 'SHARED_FOLDER_UID')

puts "Folder created with UID: #{folder_uid}"

# 既存フォルダの下にサブフォルダを作成
subfolder_uid = secrets_manager.create_folder(
  'Subfolder',
  parent_uid: folder_uid
)

puts "Subfolder created: #{subfolder_uid}"
```

## フォルダの更新

```
update_folder(folder_uid, new_name)
```

| パラメータ       | 型      | 必須 | デフォルト | 説明                |
| ----------- | ------ | -- | ----- | ----------------- |
| folder\_uid | String | はい | -     | 名前を変更する対象フォルダのUID |
| new\_name   | String | はい | -     | 新しいフォルダ名          |

### レスポンス

**型:** `void`

指定したフォルダの名前を変更します。

#### 使用例

```ruby
require 'keeper_secrets_manager'

secrets_manager = KeeperSecretsManager.from_file('keeper_config.json')

# フォルダ名を変更
secrets_manager.update_folder('FOLDER_UID', 'New Folder Name')

puts "Folder renamed successfully"
```

## フォルダの削除

```ruby
delete_folder(folder_uid, force: false)
```

| パラメータ        | 型         | 必須 | デフォルト   | 説明                       |
| ------------ | --------- | -- | ------- | ------------------------ |
| `folder_uid` | `String`  | はい | -       | 削除対象のフォルダUID             |
| `force`      | `Boolean` | 任意 | `false` | true の場合、フォルダ内の内容物もすべて削除 |

### レスポンス

**型:** `void`

指定したフォルダをボルトから削除します。

### 使用例

```ruby
require 'keeper_secrets_manager'

secrets_manager = KeeperSecretsManager.from_file('keeper_config.json')

# 空のフォルダを削除
secrets_manager.delete_folder('FOLDER_UID')

# フォルダを強制削除（内容物もすべて削除）
secrets_manager.delete_folder('FOLDER_UID', force: true)

puts "Folder deleted"

# 複数フォルダを削除
folder_uids = ['UID1', 'UID2', 'UID3']
folder_uids.each do |uid|
  secrets_manager.delete_folder(uid, force: true)
end
```

## キャッシュ

シークレットをローカルにキャッシュすることで、パフォーマンスを向上できます。

#### CachingStorageの使用

```ruby
require 'keeper_secrets_manager'

# 基本ストレージを作成
base_storage = KeeperSecretsManager::Storage::FileStorage.new('keeper_config.json')

# キャッシュでラップ（TTLは600秒）
cached_storage = KeeperSecretsManager::Storage::CachingStorage.new(base_storage, 600)

# キャッシュ対応ストレージを使用して初期化
secrets_manager = KeeperSecretsManager.new(config: cached_storage)

# 最初の呼び出しではサーバーから取得
records = secrets_manager.get_secrets

# TTL内の呼び出しではキャッシュを使用
records = secrets_manager.get_secrets  # キャッシュされたデータを使用
```

## 高度な構成

#### カスタムホスト名

```ruby
require 'keeper_secrets_manager'

# 欧州データセンター
secrets_manager = KeeperSecretsManager.new(
  token: 'EU:ONE_TIME_TOKEN',
  hostname: 'keepersecurity.eu',
  config: storage
)

# 豪州データセンター
secrets_manager = KeeperSecretsManager.new(
  token: 'AU:ONE_TIME_TOKEN',
  hostname: 'keepersecurity.com.au',
  config: storage
)
```

#### SSL証明書検証

```ruby
require 'keeper_secrets_manager'

secrets_manager = KeeperSecretsManager.new(
  config: storage,
  verify_ssl_certs: true  # 既定値は true
)
```

#### カスタムロギング

```ruby
require 'keeper_secrets_manager'
require 'logger'

# カスタムロガーを作成
logger = Logger.new(STDOUT)
logger.level = Logger::DEBUG

secrets_manager = KeeperSecretsManager.new(
  config: storage,
  logger: logger,
  log_level: Logger::DEBUG
)
```

#### すべての構成オプション

```ruby
require 'keeper_secrets_manager'

secrets_manager = KeeperSecretsManager.new(
  token: 'US:ONE_TIME_TOKEN',           # ワンタイムアクセストークン
  config: storage,                      # 構成ストレージ
  hostname: 'keepersecurity.com',       # APIホスト名
  verify_ssl_certs: true,               # SSL検証
  logger: Logger.new(STDOUT),           # カスタムロガー
  log_level: Logger::WARN,              # ログレベル
  custom_post_function: my_post_func    # カスタムHTTPハンドラー
)
```

## フィールドタイプヘルパー

タイプ付きフィールドを簡単に作成するための便利な方法が用意されています。

```ruby
require 'keeper_secrets_manager'

# フィールド作成にヘルパーを使用
fields = [
  KeeperSecretsManager::FieldTypes::Helpers.login('admin'),
  KeeperSecretsManager::FieldTypes::Helpers.password('SecurePass123!'),
  KeeperSecretsManager::FieldTypes::Helpers.url('https://example.com'),
  KeeperSecretsManager::FieldTypes::Helpers.host(
    hostname: '192.168.1.100',
    port: 22
  ),
  KeeperSecretsManager::FieldTypes::Helpers.name(
    first: 'John',
    middle: 'Q',
    last: 'Doe'
  ),
  KeeperSecretsManager::FieldTypes::Helpers.address(
    street1: '123 Main St',
    city: 'New York',
    state: 'NY',
    zip: '10001'
  )
]

# レコード作成用にハッシュへ変換
record_data = {
  type: 'login',
  title: 'Server with Helpers',
  fields: fields.map(&:to_h)
}

# 必須の folder_uid を指定して作成オプションを作成
options = KeeperSecretsManager::Dto::CreateOptions.new(folder_uid: 'FOLDER_UID')
record_uid = secrets_manager.create_secret(record_data, options)
```

## ダイナミックレコードアクセス

Ruby SDKでは、`method_missing` を利用して JavaScript のような動的フィールドアクセスを実現しています。

```ruby
# レコードを取得
record = secrets_manager.get_secrets(['RECORD_UID']).first

# 動的ゲッター
login = record.login          # フィールド値を返す
password = record.password    # フィールド値を返す
url = record.url              # フィールド値を返す

# 動的セッター
record.password = 'NewPassword123!'
record.url = 'https://newurl.example.com'

# フィールドが存在するか確認
if record.respond_to?(:oneTimeCode)
  # oneTimeCode フィールドからTOTPコードを生成
  require 'keeper_secrets_manager/totp'
  totp_url = record.oneTimeCode
  totp_params = KeeperSecretsManager::TOTP.parse_url(totp_url)
  totp_code = KeeperSecretsManager::TOTP.generate_code(
    totp_params['secret'],
    algorithm: totp_params['algorithm'],
    digits: totp_params['digits'],
    period: totp_params['period']
  )
end

# すべてのフィールドにハッシュ形式でアクセス
fields = record.fields
fields.each do |type, values|
  puts "#{type}: #{values.join(', ')}"
end
```
