# .NET SDK

<figure><img src="https://859776093-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPL6k1aGsLiFiiJ3Y7zCl%2Fuploads%2FVJaRl0bkCjelj33O9sAO%2Fimage.png?alt=media&#x26;token=35a939c2-41a0-45e1-9202-faa71a630341" alt=""><figcaption></figcaption></figure>

## ダウンロードとインストール <a href="#download-and-installation" id="download-and-installation"></a>

### 要件 <a href="#prerequisites" id="prerequisites"></a>

`dotnet add package Keeper.SecretsManager`

詳しくは[こちらのウェブサイト](https://www.nuget.org/packages/Keeper.SecretsManager/)をご覧ください。

### ソースコード <a href="#source-code" id="source-code"></a>

.Netのソースコードは、[GitHubリポジトリ](https://github.com/Keeper-Security/secrets-manager/tree/master/sdk/dotNet)で入手できます。

## SDKの使用 <a href="#using-the-sdk" id="using-the-sdk"></a>

### ストレージの初期化 <a href="#initialize-storage" id="initialize-storage"></a>

{% hint style="info" %}
トークンのみを使用して (後で使用するために) 新しい設定を生成するには、トークンをバインドして、`config.json` 完全に読み込むための読み取り操作が少なくとも1回必要です。
{% endhint %}

シークレットを取得するには、まずマシンのローカルストレージを初期化する必要があります。

```csharp
SecretsManagerClient.InitializeStorage(storage: IKeyValueStorage, oneTimeToken: string, hostName: string = null)
```

<table><thead><tr><th width="162">パラメータ</th><th width="186">型</th><th width="150">必須</th><th width="150">デフォルト</th><th>説明</th></tr></thead><tbody><tr><td><code>storage</code></td><td><code>KeyValueStorage</code></td><td>はい</td><td></td><td></td></tr><tr><td><code>clientKey</code></td><td>String</td><td>オプション</td><td>null</td><td></td></tr><tr><td><code>hostName</code></td><td>String</td><td>オプション</td><td>null</td><td></td></tr></tbody></table>

<table data-header-hidden><thead><tr><th width="162">パラメータ</th><th width="186">型</th><th width="150">必須</th><th width="150">デフォルト</th><th>説明</th></tr></thead><tbody><tr><td>パラメータ</td><td>型</td><td>必須</td><td>デフォルト</td><td>説明</td></tr><tr><td><code>storage</code></td><td><code>IKeyValueStorage</code></td><td>はい</td><td></td><td>構成を永続化するストレージ実装</td></tr><tr><td><code>oneTimeToken</code></td><td><code>string</code></td><td>はい</td><td></td><td>構成の初期化に使用するワンタイムアクセストークン</td></tr><tr><td><code>hostName</code></td><td><code>string</code></td><td>任意</td><td>null</td><td>Keeperサーバーのホスト名（省略時はトークンから自動検出）</td></tr></tbody></table>

#### **使用例** <a href="#example-usage" id="example-usage"></a>

```csharp
var storage = new LocalConfigStorage("ksm-config.json");
SecretsManagerClient.InitializeStorage(storage, "[One Time Access Token]");
// トークンのみを使用して (後で使用するために) 設定を生成するには
// トークンをバインドするアクセス操作が少なくとも1回必要です
var options = new SecretsManagerOptions(storage);
await SecretsManagerClient.GetSecrets(options);
```

{% hint style="success" %}
**自動ファイルセキュリティ** (v17.1.0以降)

.NET SDKでは、設定ファイルおよびキャッシュファイルのセキュリティが自動的に保護されます。

* **Unix/macOS**: `chmod 600` (所有者のみ読み取り/書き込み可能) が設定されます。
* **Windows**: ACLが現在のユーザーのみに制限されます。

保護対象のファイル

* `ksm-config.json` (またはカスタム構成ファイル名)
* `cache.dat` (キャッシュを使用する場合)

追加の設定は不要です。SDKによって自動的に処理されます。
{% endhint %}

#### シークレットマネージャーのオプション <a href="#secrets-manager-options" id="secrets-manager-options"></a>

```csharp
SecretsManagerOptions(
        IKeyValueStorage storage, 
        QueryFunction queryFunction = null, 
        bool allowUnverifiedCertificate = false, 
        string proxyUrl = null
)
```

<table data-header-hidden><thead><tr><th width="256.1796875">パラメータ</th><th width="186">型</th><th width="150">必須</th><th width="150">デフォルト</th><th data-hidden>説明</th></tr></thead><tbody><tr><td>パラメータ</td><td>型</td><td>必須</td><td>デフォルト</td><td>説明</td></tr><tr><td><code>storage</code></td><td><code>IKeyValueStorage</code></td><td>はい</td><td></td><td></td></tr><tr><td><code>queryFunction</code></td><td><code>QueryFunction</code></td><td>任意</td><td>null</td><td></td></tr><tr><td><code>allowUnverifiedCertificate</code></td><td><code>bool</code></td><td>任意</td><td>false</td><td></td></tr><tr><td><code>proxyUrl</code></td><td><code>string</code></td><td>任意</td><td>null</td><td></td></tr></tbody></table>

### シークレットの取得 <a href="#retrieve-secrets" id="retrieve-secrets"></a>

```csharp
GetSecrets(options: SecretsManagerOptions, recordsFilter: string[] = null): Task<KeeperSecrets>
```

| パラメータ           | 型                       | 必須 | デフォルト  | 説明           |
| --------------- | ----------------------- | -- | ------ | ------------ |
| `options`       | `SecretsManagerOptions` | はい |        | ストレージとクエリの設定 |
| `recordsFilter` | `string[]`              | 任意 | `null` | レコードの検索フィルタ  |

**レスポンス**

型: `KeeperSecrets`

すべてのKeeperのレコード、または指定したフィルタ条件に一致するレコードを含むオブジェクト

**使用例**

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

```csharp
var options = new SecretsManagerOptions(storage, testPostFunction);
var secrets = await SecretsManagerClient.GetSecrets(options);
```

### タイトルでシークレットを取得 <a href="#retrieve-secrets-by-title" id="retrieve-secrets-by-title"></a>

```csharp
// 一致するレコードをすべて取得
async Task<IEnumerable<KeeperRecord>> GetSecretsByTitle(SecretsManagerOptions options, string recordTitle)

// 最初に一致したレコードだけを取得
async Task<KeeperRecord> GetSecretByTitle(SecretsManagerOptions options, string recordTitle)
```

<table><thead><tr><th width="178.10385756676556">パラメータ</th><th width="226.46137991694417">型</th><th width="150">必須</th><th>説明</th></tr></thead><tbody><tr><td><code>options</code></td><td>SecretsManagerOptions</td><td>はい</td><td>事前に設定されたオプション</td></tr><tr><td><code>recordTitle</code></td><td>string</td><td>はい</td><td>検索するレコードタイトル</td></tr></tbody></table>

**使用例**

```csharp
using System;
using System.Threading.Tasks;
using SecretsManager;

private static async Task getOneIndividualSecret()
{
    var storage = new LocalConfigStorage("ksm-config.json");
    var options = new SecretsManagerOptions(storage);
    var records = await SecretsManagerClient.GetSecretsByTitle(
            options, "My Credentials");
    foreach (var record in records)
    {
        Console.WriteLine(record.RecordUid + " - " + record.Data.title);
        foreach (var field in record.Data.fields)
        {
            Console.WriteLine("\t" + field.label + " (" + field.type + "): [" + String.Join(", ", field.value) + "]");
        }
    }
}
```

### シークレットから値を取得 <a href="#retrieve-values-from-a-secret" id="retrieve-values-from-a-secret"></a>

#### パスワードを取得 <a href="#retrieve-a-password" id="retrieve-a-password"></a>

{% tabs %}
{% tab title="パスワードを取得" %}

```csharp
secret.FieldValue("password")
```

{% endtab %}

{% tab title="パスワード取得の例e" %}

```csharp
var storage = new LocalConfigStorage(configName);
Console.WriteLine($"Local Config Storage opened from the file {configName}");
if (clientKey != null)
    SecretsManagerClient.InitializeStorage(storage, "<One Time Access Token>");

var options = new SecretsManagerOptions(storage);
// シークレットを取得
var secrets= (await SecretsManagerClient.GetSecrets(options)).Records;

// 最初のシークレットからパスワードを取得
var firstSecret= secrets[0];
var password = firstSecret.FieldValue("password").ToString();
```

{% endtab %}
{% endtabs %}

フィールドタイプはKeeper[レコードタイプ](/enterprise-guide/jp/record-types.md)に基づきます。利用可能なフィールドの詳細な一覧については、コマンダーで [`record-type-info`](/keeperpam/jp/commander-cli/command-reference/record-commands/record-type-commands.md#record-type-info-command) コマンドをご参照ください。

#### Keeper表記法を使用して他のフィールドを取得 <a href="#retrieve-other-fields-using-keeper-notation" id="retrieve-other-fields-using-keeper-notation"></a>

{% tabs %}
{% tab title="値を取得" %}

```csharp
GetValue(KeeperSecrets secrets, string notation)
```

{% endtab %}

{% tab title="使用例" %}

```csharp
var storage = new LocalConfigStorage(configName);
Console.WriteLine($"Local Config Storage opened from the file {configName}");
if (clientKey != null)
    SecretsManagerClient.InitializeStorage(storage, "<One Time Access Token>");

var options = new SecretsManagerOptions(storage);
// シークレットを取得
var secrets = (await SecretsManagerClient.GetSecrets(options)).Records;

// ドット記法を使用してログインフィールドの値を取得
var password = Notation.GetValue(secrets, "BediNKCMG21ztm5xGYgNww/field/login");
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Keeper表記法の形式と機能については、[Keeper表記法のドキュメント](/keeperpam/jp/secrets-manager/about/keeper-notation.md)をご参照ください。
{% endhint %}

<table data-header-hidden><thead><tr><th>パラメータ</th><th>型</th><th width="200">必須</th><th>デフォルト</th><th>説明</th></tr></thead><tbody><tr><td>パラメータ</td><td>型</td><td>必須</td><td>デフォルト</td><td>説明</td></tr><tr><td><code>secrets</code></td><td><code>KeeperSecrets</code></td><td>はい</td><td></td><td>照会するシークレット</td></tr><tr><td><code>notation</code></td><td><code>string</code></td><td>はい</td><td></td><td>ドット記法形式のフィールドクエリ</td></tr></tbody></table>

**TOTPコードを取得**

{% tabs %}
{% tab title="TOTPコードを取得" %}

```csharp
CryptoUtils.GetTotpCode(string url)
```

{% endtab %}

{% tab title="使用例" %}

```csharp
var storage = new LocalConfigStorage(configName);
Console.WriteLine($"Local Config Storage opened from the file {configName}");
if (clientKey != null)
    SecretsManagerClient.InitializeStorage(storage, "<One Time Access Token>");

var options = new SecretsManagerOptions(storage);
// シークレットを取得
var secrets = (await SecretsManagerClient.GetSecrets(options)).Records;

// レコードからTOTP urlを取得
var url = Notation.GetValue(secrets, "BediNKCMG21ztm5xGYgNww/field/OneTimeCode");

// TOTPコードを取得
var totp = CryptoUtils.GetTotpCode(url);
Console.WriteLine(totp.Code);
```

{% endtab %}
{% endtabs %}

<table data-header-hidden><thead><tr><th>パラメータ</th><th>型</th><th width="200">必須</th><th>デフォルト</th><th>説明</th></tr></thead><tbody><tr><td>パラメータ</td><td>型</td><td>必須</td><td>デフォルト</td><td>説明</td></tr><tr><td><code>url</code></td><td><code>string</code></td><td>はい</td><td></td><td>TOTP Url</td></tr></tbody></table>

### シークレットの値を更新 <a href="#update-values-in-a-secret" id="update-values-in-a-secret"></a>

{% hint style="warning" %}
レコード更新コマンドは成功してもローカルのレコードデータが更新されません（特に更新後のレコードリビジョン）。そのため、すでに更新されたレコードに連続して更新を行うと、リビジョンの不一致によって失敗します。各更新バッチの後には、必ず更新されたすべてのレコードを再読み込みしてください。
{% endhint %}

#### 変更をシークレットに保存 <a href="#save-changes-to-a-secret" id="save-changes-to-a-secret"></a>

{% tabs %}
{% tab title="シークレットを更新" %}

```csharp
UpdateSecret(options: SecretsManagerOptions, record: KeeperRecord, transactionType: UpdateTransactionType? = null);
```

{% endtab %}

{% tab title="使用例" %}

```csharp
var options = new SecretsManagerOptions(storage, testPostFunction);
await SecretsManagerClient.UpdateSecret(options, secret);
```

{% endtab %}

{% tab title="トランザクション更新" %}

```csharp
var storage = new LocalConfigStorage(configName);
var options = new SecretsManagerOptions(storage);

// シークレットを取得
var secrets = (await SecretsManagerClient.GetSecrets(options)).Records;

// 最初のシークレットを取得
var secret = secrets[0];

// レコードのパスワードをローテーション
secret.UpdateFieldValue("password", "MyNewPassword");
// トランザクションを開始
await SecretsManagerClient.UpdateSecret(options, secret, UpdateTransactionType.Rotation);
// リモートホストのパスワードをローテーション
success = rotateRemoteSshPassword("MyNewPassword");
// トランザクションを完了（コミットまたはロールバック）
await SecretsManagerClient.CompleteTransaction(options, secret.RecordUid, rollback: !success);
```

{% endtab %}
{% endtabs %}

<table><thead><tr><th width="129">パラメータ</th><th width="243">型</th><th width="103">必須</th><th width="89">デフォルト</th><th>説明</th></tr></thead><tbody><tr><td><code>options</code></td><td><code>SecretsManagerOptions</code></td><td>はい</td><td></td><td>ストレージとクエリの設定</td></tr></tbody></table>

<table data-header-hidden><thead><tr><th width="162">パラメータ</th><th width="243">型</th><th width="103">必須</th><th width="89">デフォルト</th><th>説明</th></tr></thead><tbody><tr><td>パラメータ</td><td>型</td><td>必須</td><td>デフォルト</td><td>説明</td></tr><tr><td><code>options</code></td><td><code>SecretsManagerOptions</code></td><td>はい</td><td></td><td>ストレージとクエリの設定</td></tr><tr><td><code>record</code></td><td><code>KeeperRecord</code></td><td>はい</td><td></td><td>更新されたフィールド値を含むレコード</td></tr><tr><td><code>transactionType</code></td><td><code>UpdateTransactionType?</code></td><td>任意</td><td>null</td><td>トランザクション（2フェーズ）更新には <code>Rotation</code> を指定</td></tr></tbody></table>

`UpdateSecret` を使用して、シークレットレコードに加えた変更を保存してください。`UpdateSecret` を実行するまで、変更はKeeperボルトに反映されません。

#### フィールド値を更新 <a href="#update-a-field-value" id="update-a-field-value"></a>

{% tabs %}
{% tab title="フィールド値を更新" %}

```csharp
UpdateFieldValue(string fieldType, object value)
```

{% endtab %}

{% tab title="使用例" %}

```csharp
var storage = new LocalConfigStorage(configName);
Console.WriteLine($"Local Config Storage opened from the file {configName}");
if (clientKey != null)
    SecretsManagerClient.InitializeStorage(storage, "<One Time Access Token>");

var options = new SecretsManagerOptions(storage);
// シークレットを取得
var secrets= (await SecretsManagerClient.GetSecrets(options)).Records;

// 最初のシークレットからパスワードを取得
var firstSecret= secrets[0];

// ログインフィールドを更新
firstSecret.UpdateFieldValue("login", "My New Login");

// タイトルとノートを更新
firstSecret.Data.title = "New Title";
firstSecret.Data.notes = "New Notes";

// 変更を保存
await SecretsManagerClient.UpdateSecret(options, firstSecret);
```

{% endtab %}
{% endtabs %}

| パラメータ       | 型        | 必須 | デフォルト | 説明          |
| ----------- | -------- | -- | ----- | ----------- |
| `fieldType` | `string` | はい |       | 更新するフィールド   |
| `value`     | `object` | はい |       | フィールドに設定する値 |

#### ランダムなパスワードを生成 <a href="#generate-a-random-password" id="generate-a-random-password"></a>

<table><thead><tr><th width="203.7142857142857">パラメータ</th><th width="150">型</th><th width="150">必須</th><th>デフォルト</th></tr></thead><tbody><tr><td>length</td><td><code>int</code></td><td>オプション</td><td>64</td></tr><tr><td>lowercase</td><td><code>int</code></td><td>オプション</td><td>0</td></tr><tr><td>uppercase</td><td><code>int</code></td><td>オプション</td><td>0</td></tr><tr><td>digits</td><td><code>int</code></td><td>オプション</td><td>0</td></tr><tr><td>specialCharacters</td><td><code>int</code></td><td>オプション</td><td>0</td></tr></tbody></table>

{% tabs %}
{% tab title="Generate Password" %}

```csharp
CryptoUtils.GeneratePassword(
    int minLength = 32, 
    int? lowercase = null, 
    int? uppercase = null, 
    int? digits = null, 
    int? specialCharacters = null, 
    string specialCharacterSet = AsciiSpecialCharacters
)
```

{% endtab %}

{% tab title="使用例" %}

```csharp
// 32文字のパスワードを、文字種のバランスよい配分で生成
var password = CryptoUtils.GeneratePassword();

// 64文字のパスワードを、数字を少なくとも10、特殊文字を少なくとも5含めて生成
var strongPassword = CryptoUtils.GeneratePassword(minLength: 64, digits: 10, specialCharacters: 5);

// 16文字の英数字のみのパスワード（特殊文字なし）を生成
var alphanumeric = CryptoUtils.GeneratePassword(minLength: 16, specialCharacters: 0);

// 新しいパスワードでレコードを更新
firstRecord.UpdateFieldValue("password", password);
await SecretsManagerClient.UpdateSecret(options, firstRecord);
```

{% endtab %}
{% endtabs %}

<table><thead><tr><th width="203.7142857142857">パラメータ</th><th width="150">型</th><th width="150">必須</th><th>デフォルト</th></tr></thead><tbody><tr><td>minLength</td><td><code>int</code></td><td>任意</td><td>32</td></tr><tr><td>lowercase</td><td><code>int?</code></td><td>任意</td><td>null</td></tr><tr><td>uppercase</td><td><code>int?</code></td><td>任意</td><td>null</td></tr><tr><td>digits</td><td><code>int?</code></td><td>任意</td><td>null</td></tr><tr><td>specialCharacters</td><td><code>int?</code></td><td>任意</td><td>null</td></tr><tr><td>specialCharacterSet</td><td><code>string</code></td><td>任意</td><td><code>"!@#$%()+;&#x3C;>=?[]{}^.,</code></td></tr></tbody></table>

各パラメータは、その文字種をパスワードに含める最小個数を表します。`null` の場合、ジェネレーターはすべての文字カテゴリにわたってバランスの取れた配分を使用します。`specialCharacterSet` パラメータは、候補となる特殊文字の集合を制御します。

### ファイルのダウンロード <a href="#download-a-file" id="download-a-file"></a>

```csharp
DownloadFile(file: KeeperFile): ByteArray
```

| パラメータ  | 型            | 必須 | デフォルト | 説明           |
| ------ | ------------ | -- | ----- | ------------ |
| `file` | `KeeperFile` | はい |       | ダウンロードするファイル |

**レスポンス**

型: `ByteArray`

ダウンロード用のファイルのバイト配列

### **サムネイル**のダウンロード <a href="#download-a-thumbnail" id="download-a-thumbnail"></a>

```csharp
DownloadThumbnail(file: KeeperFile): ByteArray
```

| パラメータ  | 型            | 必須 | デフォルト | 説明                  |
| ------ | ------------ | -- | ----- | ------------------- |
| `file` | `KeeperFile` | はい |       | ダウンロードするサムネイル付きファイル |

**レスポンス**

型: `ByteArray`

ダウンロード用サムネイルのバイト配列

### ファイルのアップロード <a href="#upload-a-file" id="upload-a-file"></a>

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

```csharp
UploadFile(SecretsManagerOptions options, KeeperRecord ownerRecord, KeeperFileUpload file)
```

<table><thead><tr><th width="184.14763231197773">パラメータ</th><th width="224.99431983802478">型</th><th width="150">必須</th><th>説明</th></tr></thead><tbody><tr><td><code>options</code></td><td>SecretsManagerOptions</td><td>はい</td><td>ストレージとクエリの設定</td></tr><tr><td><code>ownerRecord</code></td><td>KeeperRecord</td><td>はい</td><td>アップロードされたファイルを添付するレコード</td></tr><tr><td><code>file</code></td><td>KeeperFileUpload</td><td>はい</td><td>アップロードするファイル</td></tr></tbody></table>

Keeperファイルアップロードオブジェクトを作成

```csharp
KeeperFileUpload(string name, string title, string type, byte[] data)
```

<table><thead><tr><th width="169">パラメータ</th><th width="150">型</th><th width="150">必須</th><th>説明</th></tr></thead><tbody><tr><td><code>name</code></td><td>string</td><td>はい</td><td>アップロード後にKeeperに格納されるファイルの名前</td></tr><tr><td><code>title</code></td><td>string</td><td>はい</td><td>アップロード後にKeeperに格納されるファイルのタイトル</td></tr><tr><td><code>type</code></td><td>string</td><td>はい</td><td>ファイルのデータのMIMEタイプ（「application/octet-stream」など）</td></tr><tr><td><code>data</code></td><td>byte[]</td><td>はい</td><td>バイト型のファイルデータ</td></tr></tbody></table>

**使用例**

```csharp
using System;
using System.Threading.Tasks;
using SecretsManager;

private static async Task uploadFile()
{
    // ストレージとオプションを初期化
    var storage = new LocalConfigStorage("ksm-config.json");
    var options = new SecretsManagerOptions(storage);
    
    // ファイルを添付するレコードを取得
    var records = (await SecretsManagerClient.GetSecrets(
            options, new[] { "XXX" })
        ).Records;
        
    var ownerRecord = records[0];
    
    // アップロードするファイルデータを取得
    var bytes = await File.ReadAllBytesAsync("my-file.json");
    var myFile = new KeeperFileUpload(
        "my-file1.json",
        "My File",
        null,
        bytes
    );
       
    // 選択したレコードにファイルをアップロード                     
    await SecretsManagerClient.UploadFile(options, ownerRecord, myFile);
    
}
```

### シークレットの作成 <a href="#create-a-secret" id="create-a-secret"></a>

#### 要件 <a href="#create-a-secret-prerequisites" id="create-a-secret-prerequisites"></a>

* 共有フォルダのUID
  * 共有フォルダへはシークレットマネージャーアプリケーションからアクセスできること
  * あなたとシークレットマネージャーアプリケーションに編集権限が付与されていること
  * 共有フォルダには、少なくとも1つのレコードが存在すること
* 作成されたレコードとレコードのフィールドは正しく書式設定されていること
* レコードタイプごとの想定されるフィールド形式については、[こちらのページ](/enterprise-guide/jp/record-types.md)をご参照ください
* TOTPフィールドには、KSM SDK以外で生成されたURLのみを指定できます
* レコードを作成した後、[UploadFile](#upload-a-file)を使用してファイル添付をアップロードできます

{% tabs %}
{% tab title="レコード作成" %}

```csharp
SecretsManagerClient.CreateSecret(options, folderUid, record)
```

<table><thead><tr><th width="168">パラメータ</th><th width="261">型</th><th>必須</th><th>デフォルト</th></tr></thead><tbody><tr><td><code>options</code></td><td><code>SecretsManagerOptions</code></td><td>はい</td><td></td></tr><tr><td><code>folderUid</code></td><td><code>string</code></td><td>はい</td><td></td></tr><tr><td><code>record</code></td><td><code>KeeperRecordData</code></td><td>はい</td><td></td></tr></tbody></table>
{% endtab %}

{% tab title="サブフォルダでレコード作成" %}

```csharp
SecretsManagerClient.CreateSecret2(options, createOptions, record, folders)
```

<table><thead><tr><th width="168">パラメータ</th><th width="261">型</th><th>必須</th><th>デフォルト</th></tr></thead><tbody><tr><td><code>options</code></td><td><code>SecretsManagerOptions</code></td><td>はい</td><td></td></tr><tr><td><code>createOptions</code></td><td><code>CreateOptions</code></td><td>はい</td><td></td></tr><tr><td><code>record</code></td><td><code>KeeperRecordData</code></td><td>はい</td><td></td></tr><tr><td><code>folders</code></td><td><code>KeeperFolder[]</code></td><td>いいえ</td><td></td></tr></tbody></table>
{% endtab %}

{% tab title="ログイン情報レコードの例" %}
この例では、ログイン値と生成されたパスワードを含むログインタイプのレコードを作成します。

{% hint style="info" %}
例にある `[FOLDER UID]` をシークレットマネージャーがアクセスできる共有フォルダのUIDに置き換えます。
{% endhint %}

```csharp
var newRecord = new KeeperRecordData{type = "login", title = "Sample KSM Record: C#"};

newRecord.fields = new[]
{
    new KeeperRecordField { type = "login", value = new[] { "My Username" } },
    new KeeperRecordField { type = "password", value = new[] { CryptoUtils.GeneratePassword() } },
};
newRecord.notes = "This is a C# record creation example";

var recordUid = await SecretsManagerClient.CreateSecret(options, folderUid, newRecord);
```

{% endtab %}

{% tab title="カスタムタイプの例" %}
この例では、カスタムのレコードタイプのレコードを作成します。

{% hint style="info" %}
例にある `[FOLDER UID]` をシークレットマネージャーがアクセスできる共有フォルダのUIDに置き換えます。
{% endhint %}

```csharp
var newRecord = new KeeperRecordData();
newRecord.type = "Custom Login";
newRecord.title = "Sample Custom Type KSM Record: C#";
newRecord.fields = new[]
{
    new KeeperRecordField { 
        type = "host",
        value = new[] 
        {
            new Dictionary<string, string>
            {
                { "hostName", "127.0.0.1"},
                { "port", "8080"}
            }
        },
        label = "My Custom Host lbl",
        required = true
    },
    
    new KeeperRecordField { 
        type = "login",
        value = new[] { "login@email.com" },
        required = true,
        label = "My Custom Login lbl"
    },
    
    new KeeperRecordField
    {
        type = "password",
        value = new[] { CryptoUtils.GeneratePassword() },
        required = true,
        label = "My Custom Password lbl"
    },
    
    new KeeperRecordField
    {
        type = "url",
        value = new[] { "http://localhost:8080/login" },
        label = "My Login Page",
        required = true
    },
    
    new KeeperRecordField { 
        type = "securityQuestion",
        value = new[]
        {
            new Dictionary<string, string>
            {
                {"question", "What is one plus one (write just a number)"},
                { "answer", "2" }
            }
        },
        label = "My Question 1",
        required = true
    },
    
    new KeeperRecordField { 
        type = "phone",
        value = new[]
        {
            new Dictionary<string,string>
            {
                { "region", "US" },
                { "number", "510-444-3333" },
                { "ext", "2345" },
                { "type", "Mobile" }
            }
        },
        label = "My Private Phone",
        privacyScreen = true
    },

    new KeeperRecordField
    {
        type = "date",
        value = new[] {(object) 1641934793000 },
        label = "My Date Lbl"
    },
    
    new KeeperRecordField { 
        type = "name",
        value = new[]
        {
            new Dictionary<string, string>
            {
                {"first", "John"},
                {"middle", "Patrick"},
                {"last", "Smith"}
            }
        },
        required = true
    },
    new KeeperRecordField
    {
        type = "oneTimeCode",
        value = new[]
        {
            "otpauth://totp/Example:alice@google.com?secret=JBSWY3DPEHPK3PXP&issuer=Example"
        },
        label = "My TOTP",
        required = true
    }
};
newRecord.notes = "\tThis custom type record was created\n\tvia .NET SDK copied from https://docs.keeper.io/secrets-manager/secrets-manager/developer-sdk-library/.net-sdk";

var recordUid = await SecretsManagerClient.CreateSecret(options, "[FOLDER_UID]", newRecord);

```

{% endtab %}
{% endtabs %}

### シークレットの削除 <a href="#delete-a-secret" id="delete-a-secret"></a>

.Net KSM SDKでKeeperボルトのレコードを削除できます。

{% tabs %}
{% tab title="シークレットの削除" %}

```csharp
DeleteSecret(smOptions, recordsUids);
```

<table><thead><tr><th>パラメータ</th><th width="250.66666666666666">型</th><th align="center">必須</th></tr></thead><tbody><tr><td><code>smOptions</code></td><td><code>SecretsManagerOptions</code></td><td align="center">はい</td></tr><tr><td><code>recordsUids</code></td><td><code>string[]</code></td><td align="center">はい</td></tr></tbody></table>
{% endtab %}

{% tab title="使用例" %}

<pre class="language-csharp"><code class="lang-csharp">using SecretsManager;

// シークレットマネージャーを設定
var storage = new LocalConfigStorage("ksm-config.json");
//SecretsManagerClient.InitializeStorage(storage, "&#x3C;One Time Access Token>");
var smOptions = new SecretsManagerOptions(storage);

// UIDレコードで特定のシークレットを削除
<strong>await SecretsManagerClient.DeleteSecret(smOptions, new string[] {"EG6KdJaaLG7esRZbMnfbFA"});
</strong></code></pre>

{% endtab %}
{% endtabs %}

### キャッシュ <a href="#caching" id="caching"></a>

ネットワークにアクセスできなくなった場合にシークレットへのアクセスを失わないよう、.Net SDKではシークレットをローカルマシン上の暗号化ファイルにキャッシュできます。

**キャッシュの設定と構成**

.Net SDKでキャッシュを設定するには、`SecretsManagerOptions` オブジェクトをインスタンス化する際に、2番目の引数としてキャッシュ用のポスト関数を含めます。

.Net SDKには標準のキャッシュ機能 `cachingPostFunction` が用意されており、キャッシュされたクエリをファイルに保存します。

```csharp
var options = new SecretsManagerOptions(storage, SecretsManagerClient.CachingPostFunction);
var secrets = await SecretsManagerClient.GetSecrets(options);
```

### フォルダ <a href="#folders" id="folders"></a>

フォルダは、作成・読み取り・更新・削除 (CRUD) のすべての操作に対応しています。

### フォルダの読み取り <a href="#read-folders" id="read-folders"></a>

フォルダの完全な階層構造をダウンロードします。

```csharp
Task<KeeperFolder[]> GetFolders(SecretsManagerOptions options)
```

**レスポンス**

型: `KeeperFolder[]`

**使用例**

```csharp
using SecretsManager;

var options = new SecretsManagerOptions(new LocalConfigStorage("ksm-config.json"));
var folders = await SecretsManagerClient.GetFolders(options);
```

### フォルダの作成 <a href="#create-a-folder" id="create-a-folder"></a>

`CreateOptions` とフォルダ名の指定が必要です。`CreateOptions` 内のフォルダUIDパラメータは必須で、共有フォルダのUIDを指定します。サブフォルダのUIDは任意であり、省略された場合は親 (共有フォルダ) 直下に通常のフォルダが新規作成されます。サブフォルダは必ずしも親共有フォルダの直接の子である必要はなく、階層を深く設定することも可能です。

```csharp
Task<string> CreateFolder(SecretsManagerOptions options, CreateOptions createOptions, string folderName, KeeperFolder[] folders = null)
```

<table><thead><tr><th width="181.85161529417937">パラメータ</th><th width="242.99431983802478">型</th><th width="102">必須</th><th width="87">デフォルト</th><th>説明</th></tr></thead><tbody><tr><td><code>options</code></td><td><code>SecretsManagerOptions</code></td><td>はい</td><td></td><td>事前に設定されたオプション</td></tr><tr><td><code>createOptions</code></td><td><code>CreateOptions</code></td><td>はい</td><td></td><td>親およびサブフォルダのUID</td></tr><tr><td><code>folderName</code></td><td><code>string</code></td><td>はい</td><td></td><td>フォルダ名</td></tr><tr><td><code>folders</code></td><td><code>KeeperFolder[]</code></td><td>いいえ</td><td><code>null</code></td><td>CreateOptionsで作成した親とサブフォルダの検索に使用するフォルダのリスト</td></tr></tbody></table>

```csharp
public class CreateOptions {
    public string FolderUid { get; }
    public string SubFolderUid { get; }
}
```

```csharp
public class KeeperFolder {
        public byte[] FolderKey { get; }
        public string FolderUid { get; }
        public string ParentUid { get; }
        public string Name { get; }
}
```

**使用例**

```csharp
using SecretsManager;

var options = new SecretsManagerOptions(new LocalConfigStorage("ksm-config.json"));
var co = new CreateOptions("[PARENT_SHARED_FOLDER_UID]");
var folderUid = await SecretsManagerClient.CreateFolder(options, co, "new_folder");
```

### フォルダの更新 <a href="#update-a-folder" id="update-a-folder"></a>

フォルダのメタデータ (現在はフォルダ名のみ) を更新します。

```csharp
Task UpdateFolder(SecretsManagerOptions options, string folderUid, string folderName, KeeperFolder[] folders = null)
```

<table><thead><tr><th width="154.85161529417937">パラメータ</th><th width="243.99431983802478">型</th><th width="100">必須</th><th width="88">デフォルト</th><th>説明</th></tr></thead><tbody><tr><td><code>options</code></td><td><code>SecretsManagerOptions</code></td><td>はい</td><td></td><td>事前に設定されたオプション</td></tr><tr><td><code>folderUid</code></td><td><code>string</code></td><td>はい</td><td></td><td>フォルダのUID</td></tr><tr><td><code>folderName</code></td><td><code>string</code></td><td>はい</td><td></td><td>新しいフォルダ名</td></tr><tr><td><code>folders</code></td><td><code>KeeperFolder[]</code></td><td>いいえ</td><td><code>null</code></td><td>親フォルダの検索に使用するフォルダのリスト</td></tr></tbody></table>

**使用例**

```csharp
using SecretsManager;

var options = new SecretsManagerOptions(new LocalConfigStorage("ksm-config.json"));
await SecretsManagerClient.UpdateFolder(options, "[FOLDER_UID]", "new_folder_name");
```

### フォルダの削除 <a href="#delete-folders" id="delete-folders"></a>

フォルダのリストを削除します。空でないフォルダを削除するには、`forceDeletion` フラグを使用します。

{% hint style="info" %}
`forceDeletion` を使用する場合、親フォルダとその子フォルダのUIDを同時に送信しないでください。削除の順序によってはエラーになることがあります（例: 親が子より先に強制削除される場合など）。リストが常にFIFO順で処理される保証はありません。
{% endhint %}

{% hint style="info" %}
ボルトに存在しないフォルダのUIDやKSMアプリケーションで共有されていないフォルダのUIDがあっても、エラーにはなりません。
{% endhint %}

```csharp
Task DeleteFolder(SecretsManagerOptions options, string[] folderUids, bool forceDeletion = false)
```

<table><thead><tr><th width="180.85161529417937">パラメータ</th><th width="242.99431983802478">型</th><th width="100">必須</th><th width="89">デフォルト</th><th>説明</th></tr></thead><tbody><tr><td><code>options</code></td><td><code>SecretsManagerOptions</code></td><td>はい</td><td></td><td>事前に設定されたオプション</td></tr><tr><td><code>folderUids</code></td><td><code>string[]</code></td><td>はい</td><td></td><td>フォルダUIDリスト</td></tr><tr><td><code>forceDeletion</code></td><td><code>bool</code></td><td>いいえ</td><td><code>false</code></td><td>空でないフォルダを強制的に削除</td></tr></tbody></table>

**使用例**

```csharp
using SecretsManager;

var options = new SecretsManagerOptions(new LocalConfigStorage("ksm-config.json"));
await SecretsManagerClient.DeleteFolder(options, new string[]{"[FOLDER_UID1]", "[FOLDER_UID2]"}, true);
```

### プロキシのサポート <a href="#proxy-support" id="proxy-support"></a>

.NET SDKでは、環境変数を使用する方法と、SecretsManagerOptionsに直接プロキシURLを渡す方法の2通りでプロキシを設定できます。

{% hint style="info" %}
Keeperでは、**環境変数**を使用したプロキシ設定を推奨しています。この方法により、設定情報をコード内に含めずに済み、ツールや環境間で一貫性を保ちながら、デプロイと保守を簡素化できます。
{% endhint %}

**環境変数による使用例**

```
HTTPS_PROXY=http://user:password@127.0.0.1:3128 dotnet run
```

**`SecretsManagerOptions` にURLを渡す使用例**

```csharp
var options = new SecretsManagerOptions(storage, null, false, "http://user:password@127.0.0.1:3128");
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.keeper.io/keeperpam/jp/secrets-manager/developer-sdk-library/.net-sdk.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
