# Java/Kotlin SDK

<figure><img src="/files/MU4vZ33XOOkLKQi6GF7g" alt=""><figcaption></figcaption></figure>

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

### MavenまたはGradleを使用したインストール <a href="#install-with-maven-or-gradle" id="install-with-maven-or-gradle"></a>

{% tabs %}
{% tab title="Gradle" %}
{% code title="build.gradle" %}

```gradle
repositories {
    mavenCentral()
}

dependencies {
    implementation 'com.keepersecurity.secrets-manager:core:17.2.0+'
    implementation("org.bouncycastle:bc-fips:2.1.1")
}
```

{% endcode %}
{% endtab %}

{% tab title="Maven" %}
{% code title="pom.xml" %}

```xml
<dependency>
    <groupId>com.keepersecurity.secrets-manager</groupId>
    <artifactId>core</artifactId>
    <version>[17.2.0,)</version>
</dependency>
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bc-fips</artifactId>
    <version>2.1.1</version>
</dependency>
```

{% endcode %}
{% endtab %}
{% endtabs %}

詳細については<https://central.sonatype.com/artifact/com.keepersecurity.secrets-manager/core>をご参照ください。

{% hint style="info" %}
暗号プロバイダーに関する注意事項

KeeperシークレットマネージャーSDKでは、BouncyCastleは必須ではありません。以下の暗号プロバイダーを利用できます。

* BouncyCastle FIPS ( `bc-fips:2.1.1`、上記のインストール手順で使用しているバージョン )
* Javaの標準暗号プロバイダー
* JCE互換の暗号プロバイダー

本ドキュメント内のサンプルでは、説明を目的としてBouncyCastle FIPSを使用しています。
{% endhint %}

### 暗号化プロバイダ <a href="#cryptographic-provider" id="cryptographic-provider"></a>

KeeperシークレットマネージャーSDK では、開発者が必要とされる暗号化プロバイダを使用することが想定されています。特定のプロバイダが追加されない限り、Javaランタイムのデフォルトの暗号化モジュールを使用します。本ページの例では、BouncyCastle FIPSプロバイダを使用しています。

ソースコードで、プロバイダがセキュリティコンテキストにロードされていることを確認します。

```java
fun main() {
    Security.addProvider(BouncyCastleFipsProvider())
...
```

カスタムセキュリティプロバイダーの使用方法については、[こちらのページ](https://github.com/Keeper-Security/secrets-manager/blob/dcd96317304b8ddc2b17a649ac465f5cd408491a/sdk/java/core/src/test/kotlin/com/keepersecurity/secretsManager/core/CryptoUtilsTest.kt#L11)の `CryptoUtilsTest.kt` ファイルをご参照ください。

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

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

## 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 %}

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

```java
initializeStorage(storage: KeyValueStorage, oneTimeToken: String, hostName: String? = null)
```

| パラメータ          | 型                 | 必須    | デフォルト | 説明            |
| -------------- | ----------------- | ----- | ----- | ------------- |
| `storage`      | `KeyValueStorage` | はい    |       | ストレージの実装      |
| `oneTimeToken` | String            | はい    |       | ワンタイムアクセストークン |
| `hostName`     | String            | オプション | null  | カスタムホスト名      |

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

```java
import static com.keepersecurity.secretsManager.core.SecretsManager.initializeStorage;
import com.keepersecurity.secretsManager.core.LocalConfigStorage;
import com.keepersecurity.secretsManager.core.SecretsManagerOptions;
import java.security.Security;
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;

// oneTimeTokenはストレージの初期化に一度だけ使用
// 初回実行以降の呼び出しでは「ksm-config.txt」ファイルを使用
String oneTimeToken = "[One Time Access Token]";
LocalConfigStorage storage = new LocalConfigStorage("ksm-config.txt");

Security.addProvider(new BouncyCastleFipsProvider());

try {
    initializeStorage(storage, oneTimeToken);
    SecretsManagerOptions options = new SecretsManagerOptions(storage);
    // トークンのみを使用して（後で使用するために）設定を生成するには
    // トークンをバインドするアクセス操作が少なくとも1回必要です
    //getSecrets(options)
 } catch (Exception e) {
    System.out.println(e.getMessage());
 }
```

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

```java
getSecrets(options: SecretsManagerOptions, recordsFilter: List<String> = emptyList()): KeeperSecrets
```

<table data-header-hidden><thead><tr><th>パラメータ</th><th>型</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>options</code></td><td><code>SecretsManagerOptions</code></td><td>はい</td><td></td><td>ストレージとクエリの設定</td></tr><tr><td><code>recordsFilter</code></td><td><code>List&#x3C;String></code></td><td>オプション</td><td>空のリスト</td><td>レコードの検索フィルタ</td></tr></tbody></table>

#### レスポンス <a href="#response" id="response"></a>

型: `KeeperSecrets`

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

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

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

```java
import com.keepersecurity.secretsManager.core.SecretsManagerOptions;
import com.keepersecurity.secretsManager.core.SecretsManager;
import com.keepersecurity.secretsManager.core.KeeperRecord;
import com.keepersecurity.secretsManager.core.KeeperSecrets;
import java.security.Security;
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;

// セキュリティプロバイダがロードされていることを確認
Security.addProvider(new BouncyCastleFipsProvider());

// シークレットを取得
SecretsManagerOptions options = new SecretsManagerOptions(storage);
KeeperSecrets secrets = SecretsManager.getSecrets(options);

// シークレットからレコードを取得
List<KeeperRecord> records = secrets.getRecords();
```

UIDで1つのシークレットを取得

```java
import com.keepersecurity.secretsManager.core.SecretsManagerOptions;
import com.keepersecurity.secretsManager.core.SecretsManager;
import com.keepersecurity.secretsManager.core.KeeperRecord;
import com.keepersecurity.secretsManager.core.KeeperSecrets;
import java.security.Security;
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;

// セキュリティプロバイダがロードされていることを確認
Security.addProvider(new BouncyCastleFipsProvider());

// シークレットを取得
SecretsManagerOptions options = new SecretsManagerOptions(storage);
KeeperSecrets secrets = SecretsManager.getSecrets(options);

// シークレットを取得するための1つまたは複数のUIDレコードを指定
List<String> uidFilter = List.of("[XXX]");

// フィルタを使用してシークレットを取得
KeeperSecrets secrets = SecretsManager.getSecrets(options, uidFilter);

// シークレットからレコードを取得
List<KeeperRecord> records = secrets.getRecords();
```

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

```java
// 一致するレコードをすべて取得
getSecretsByTitle(recordTitle: String): List<KeeperRecord>

// 最初に一致したレコードだけを取得
getSecretByTitle(recordTitle: String): KeeperRecord
```

<table><thead><tr><th width="178.10385756676556">パラメータ</th><th width="150">型</th><th width="150">必須</th><th>説明</th></tr></thead><tbody><tr><td><code>recordTitle</code></td><td>String</td><td>はい</td><td>検索するレコードタイトル</td></tr></tbody></table>

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

```java
import com.keepersecurity.secretsManager.core.*;
import java.util.List;

public class KSMSample {
    public static void main(String[] args){
        
        // セキュリティプロバイダが読み込まれていることを確認
        Security.addProvider(new BouncyCastleFipsProvider());

        // 事前に初期化されたストレージを取得
        KeyValueStorage storage = new LocalConfigStorage("ksm-config.json");
        try {
            SecretsManagerOptions options = new SecretsManagerOptions(storage);

            // すべてのシークレットを取得
            KeeperSecrets secrets = SecretsManager.getSecrets(options);
            
            // 取得対象レコードのタイトル
            String recordTitle = "My Credentials";
            
            // タイトルを指定してレコードを検索
            KeeperRecord myCredentials = secrets.getSecretByTitle(recordTitle);
            
            // レコードの詳細を出力
            System.out.println("Record UID: " + myCredentials.getRecordUid());
            System.out.println("Title: " + myCredentials.getData().getTitle());
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}
```

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

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

シークレットをKeeperシークレットマネージャーから取得すると、このショートカットでそのシークレットのパスワードを取得します。

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

```java
secret.getPassword()
```

{% endtab %}

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

```java
import com.keepersecurity.secretsManager.core.SecretsManagerOptions;
import com.keepersecurity.secretsManager.core.SecretsManager;
import com.keepersecurity.secretsManager.core.KeeperRecord;
import com.keepersecurity.secretsManager.core.KeeperSecrets;
import java.security.Security;
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;

// セキュリティプロバイダがロードされていることを確認
Security.addProvider(new BouncyCastleFipsProvider());

// シークレットを取得
SecretsManagerOptions options = new SecretsManagerOptions(storage);
KeeperSecrets secrets = SecretsManager.getSecrets(options);

// 最初のレコードを取得
KeeperRecord firstRecord = secrets.getRecords().get(0);

// 最初のレコードからパスワードを取得
String password = firstRecord.getPassword();
System.out.println("Password: " + password);
```

{% endtab %}
{% endtabs %}

#### フィールドを取得 <a href="#retrieve-fields" id="retrieve-fields"></a>

{% tabs %}
{% tab title="フィールドを取得" %}

```java
secret.getData().getField(<FIELD_TYPE>)
```

{% endtab %}

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

```java
import com.keepersecurity.secretsManager.core.SecretsManagerOptions;
import com.keepersecurity.secretsManager.core.SecretsManager;
import com.keepersecurity.secretsManager.core.KeeperRecord;
import com.keepersecurity.secretsManager.core.KeeperSecrets;
import java.security.Security;
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;

// セキュリティプロバイダがロードされていることを確認
Security.addProvider(new BouncyCastleFipsProvider());

// シークレットを取得
SecretsManagerOptions options = new SecretsManagerOptions(storage);
KeeperSecrets secrets = SecretsManager.getSecrets(options);

// 最初のレコードを取得
List<KeeperRecord> records = secrets.getRecords();
KeeperRecord firstRecord = secrets.getRecords().get(0);

// 最初のレコードからパスワードを取得
KeeperRecordField pwd = firstRecord.getData().getField(Password.class)
```

{% endtab %}
{% endtabs %}

フィールド値を取得するには、戻り値を対応するフィールドタイプの[クラス](/keeperpam/jp/secrets-manager/developer-sdk-library/java-sdk/record-field-classes.md)にキャストする必要があります。フィールドタイプの一覧については、[レコードタイプ](/enterprise-guide/record-types.md)をご参照ください。

#### Keeper表記法 <a href="#keeper-notation" id="keeper-notation"></a>

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

```java
Notation.getValue(secret, "<query>");
// クエリの例: <RECORD UID>/field/login
```

{% endtab %}

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

```java
import static com.keepersecurity.secretsManager.core.SecretsManager.*
import static com.keepersecurity.secretsManager.core.Notation.*;
import java.security.Security;
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;

// セキュリティプロバイダがロードされていることを確認
Security.addProvider(new BouncyCastleFipsProvider());

// シークレットを取得
KeeperSecrets secrets = getSecrets(options);

// ドット記法でログインを取得
String login = getValue(secrets, "BediNKCMG21ztm5xGYgNww/field/login");
```

{% endtab %}
{% endtabs %}

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

| パラメータ    | 型              | 必須 | デフォルト | 説明                   |
| -------- | -------------- | -- | ----- | -------------------- |
| `secret` | `KeeperRecord` | はい |       | フィールド値を取得するレコード      |
| `query`  | `String`       | はい |       | 目的のフィールドのドット記法によるクエリ |

#### TOTPコードを取得 <a href="#get-totp-code" id="get-totp-code"></a>

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

```java
TotpCode.uriToTotpCode(url)
```

{% endtab %}

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

```java
import static com.keepersecurity.secretsManager.core.Notation.*;
import static com.keepersecurity.secretsManager.core.TotpCode.*;
import java.security.Security;
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;

...

// シークレットを取得
KeeperSecrets secrets = getSecrets(options);

// レコードからTOTP urlを取得
String url= getValue(secrets, "BediNKCMG21ztm5xGYgNww/field/oneTimeCode");

// TOTPコードを取得
TotpCode totp = uriToTotpCode(url);
```

{% endtab %}
{% endtabs %}

| パラメータ | 型        | 必須 | デフォルト | 説明       |
| ----- | -------- | -- | ----- | -------- |
| `url` | `String` | はい |       | TOTP Url |

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

{% hint style="warning" %}
レコード更新コマンドが成功しても、ローカルのデータ (特にレコードのリビジョン情報) は更新されません。そのため、同じレコードを続けて更新しようとすると、リビジョンが一致しないため失敗します。これを防ぐには、レコードを更新した後に、必ずそのレコードを再読み込みしてください。
{% endhint %}

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

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

```java
updateSecret(options: SecretsManagerOptions, recordToUpdate: KeeperRecord);
```

{% endtab %}

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

```java
import com.keepersecurity.secretsManager.core.KeeperRecord;
import com.keepersecurity.secretsManager.core.KeeperSecrets;
import com.keepersecurity.secretsManager.core.SecretsManagerOptions;
import static com.keepersecurity.secretsManager.core.SecretsManager.*;

// セキュリティプロバイダがロードされていることを確認
Security.addProvider(new BouncyCastleFipsProvider());

// シークレットを取得
SecretsManagerOptions options = SecretsManagerOptions(storage);
KeeperSecrets secrets = getSecrets(options);

// 最初のレコードを更新
KeeperRecord recordToUpdate = secrets.getRecords().get(0);

// パスワードを更新
recordToUpdate.updatePassword("aP1$t367QOCvL$eM$bG#");

// タイトルとメモを更新
recordToUpdate.data.title = "New Title"
recordToUpdate.data.notes = "My Notes"

// 変更を保存
updateSecret(options, recordToUpdate); 
```

{% endtab %}

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

<pre class="language-java"><code class="lang-java">import com.keepersecurity.secretsManager.core.KeeperRecord;
import com.keepersecurity.secretsManager.core.KeeperSecrets;
import com.keepersecurity.secretsManager.core.SecretsManagerOptions;

import static com.keepersecurity.secretsManager.core.SecretsManager.*;

...

// シークレットを取得
SecretsManagerOptions options = SecretsManagerOptions(storage);
KeeperSecrets secrets = getSecrets(options);

// 最初のレコードを更新
KeeperRecord record = secrets.getRecords().get(0);

// レコードのパスワードをローテーション
record.updatePassword("aP1$t367QOCvL$eM$bG#");

// トランザクションを開始
updateSecret(options, record, transactionType = UpdateTransactionType.GENERAL);
<strong>// リモートホストでパスワードをローテーション
</strong>boolean success = rotateRemoteSshPassword("aP1$t367QOCvL$eM$bG#");
// トランザクション完了 (コミットかロールバック)
completeTransaction(options, record.recordUid, rollback = !success);
</code></pre>

{% endtab %}
{% endtabs %}

`updateSecret` を使用して、シークレットに加えた変更を保存します。正常に実行されると、変更がKeeperボルトに反映されます。

<table data-header-hidden><thead><tr><th width="206">パラメータ</th><th>型</th><th>必須</th><th>デフォルト</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>recordToUpdate</code></td><td><code>KeeperRecord</code></td><td>はい</td><td></td><td>更新するレコード</td></tr></tbody></table>

#### パスワードを更新 <a href="#update-password" id="update-password"></a>

{% tabs %}
{% tab title="パスワードを更新" %}

```java
recordToUpdate.updatePassword(password:String);

SecretsManager.updateSecret(options, recordToUpdate);
```

{% endtab %}

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

```java
import static com.keepersecurity.secretsManager.core.SecretsManager;

import com.keepersecurity.secretsManager.core.SecretsManagerOptions;
import com.keepersecurity.secretsManager.core.KeeperRecord;
import com.keepersecurity.secretsManager.core.KeeperSecrets;

// シークレットを取得
SecretsManagerOptions options = SecretsManagerOptions(storage);
KeeperSecrets secrets = getSecrets(options);

// 最初のレコードを更新
KeeperRecord recordToUpdate = secrets.getRecords().get(0);

// パスワードを更新
recordToUpdate.updatePassword("aP1$t367QOCvL$eM$bG#");

// 変更を保存
SecretsManager.updateSecret(options, recordToUpdate);
```

{% endtab %}
{% endtabs %}

| パラメータ      | 型        | 必須 | デフォルト | 説明           |
| ---------- | -------- | -- | ----- | ------------ |
| `password` | `String` | はい |       | 設定する新しいパスワード |

#### 他のフィールドを更新 <a href="#update-other-fields" id="update-other-fields"></a>

{% tabs %}
{% tab title="値を設定" %}

```java
// 形式
RecordField.getValue().set(index, value)
// 例 - ログインフィールド
recordLogin.getValue().set(0, "New Login");
```

{% endtab %}

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

```java
// 編集するフィールドを取得
Login recordLogin = (Login) recordToUpdate.getData().getField(Login.class);

// フィールド値を更新
recordLogin.getValue().set(0, "New Login");

// 変更を保存
SecretsManager.updateSecret(options, recordToUpdate);
```

{% endtab %}
{% endtabs %}

レコードの各フィールドタイプは、クラスに相当します。 フィールドの値に正しくアクセスするために、フィールドを対応するクラスにキャストします。 フィールドタイプについては、[レコードタイプ](/enterprise-guide/record-types.md)のドキュメントをご参照ください。

フィールドには複数の値を設定でき、リストでアクセスします。 この例では、1つの値のみを指定するログインフィールドを更新するため、値リスト内の1つの値を更新します。

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

{% tabs %}
{% tab title="パスワード生成" %}

```java
generatePassword(length: int, lowercase: int, uppercase: int, digits: int, specialCharacters: int)
```

{% endtab %}

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

```java
import com.keepersecurity.secretsManager.core.CryptoUtils;

// セキュリティプロバイダがロードされていることを確認
Security.addProvider(new BouncyCastleFipsProvider());

// 編集するフィールドを取得
Password recordPassword = (Password) recordToUpdate.getData().getField(Password.class);

// ランダムなパスワードを生成
String password = CryptoUtils.generatePassword();

// フィールド値を更新
recordPassword.getValue().set(0, password);

// 変更を保存
SecretsManager.updateSecret(options, recordToUpdate);
```

{% 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>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>

各パラメータは、使用する文字の種類の最小数を示します。たとえば、「uppercase」は、使用する大文字の最小数を示します。

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

{% tabs %}
{% tab title="ファイルのダウンロード" %}

```java
SecretsManager.downloadFile(file): ByteArray
```

{% endtab %}

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

```java
import static com.keepersecurity.secretsManager.core.SecretsManager;
import com.keepersecurity.secretsManager.core.KeeperRecord;
import com.keepersecurity.secretsManager.core.KeeperFile;

// セキュリティプロバイダがロードされていることを確認
Security.addProvider(new BouncyCastleFipsProvider());

// 最初のレコードから最初のファイルをダウンロード
KeeperRecord firstRecord = secrets.getRecords().get(0);
KeeperFile file = firstRecord.getFileByName("acme.cer");
byte[] fileBytes = SecretsManager.downloadFile(file);

// ファイルをディスクに書き込む
try (FileOutputStream fos = new FileOutputStream(file.getData().getName())) {
    fos.write(fileBytes);
} catch (IOException ioException){
    ioException.printStackTrace();
}
```

{% endtab %}
{% endtabs %}

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

#### レスポンス <a href="#response-2" id="response-2"></a>

型: `ByteArray`

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

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

{% tabs %}
{% tab title="サムネイルのダウンロード" %}

```java
SecretsManager.downloadThumbnail(file): ByteArray
```

{% endtab %}

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

```java
import static com.keepersecurity.secretsManager.core.SecretsManager;
import com.keepersecurity.secretsManager.core.KeeperRecord;
import com.keepersecurity.secretsManager.core.KeeperFile;

// セキュリティプロバイダがロードされていることを確認
Security.addProvider(new BouncyCastleFipsProvider());

// 最初のレコードから最初のファイルをダウンロード
KeeperRecord firstRecord = secrets.getRecords().get(0);
KeeperFile file = firstRecord.getFileByName("acme.cer");
byte[] fileBytes = SecretsManager.downloadThumbnail(file);

// ファイルをディスクに書き込む
try (FileOutputStream fos = new FileOutputStream(file.getData().getName())) {
    fos.write(fileBytes);
} catch (IOException ioException){
    ioException.printStackTrace();
}
```

{% endtab %}
{% endtabs %}

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

#### レスポンス <a href="#response-3" id="response-3"></a>

型: `ByteArray`

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

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

ファイルのアップロード

```java
uploadFile(options: SecretsManagerOptions, ownerRecord: KeeperRecord, file: KeeperFileUpload): String
```

<table><thead><tr><th width="184.14763231197773">パラメータ</th><th width="246.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ファイルアップロードオブジェクトを作成

```kotlin
KeeperFileUpload(
    val name:String,
    val title:String,
    val type:String?,
    val data:ByteArray
)
```

<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>ByteArray</td><td>はい</td><td>バイト型のファイルデータ</td></tr></tbody></table>

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

```java
import com.keepersecurity.secretsManager.core.*;

import java.io.File;
import java.io.FileInputStream;
import java.util.Arrays;

public class KSMSample {
    public static void main(String[] args){
        
        // セキュリティプロバイダがロードされていることを確認
        Security.addProvider(new BouncyCastleFipsProvider());
                
        // 事前に初期化されたストレージを取得
        KeyValueStorage storage = new LocalConfigStorage("ksm-config.json");
        try {
            SecretsManagerOptions options = new SecretsManagerOptions(storage);

            // 必要なレコードのUIDを含むフィルタを作成
            List<String> uidFilter = List.of("XXX");

            // フィルタを使用してシークレットを取得
            KeeperSecrets secrets = SecretsManager.getSecrets(options, uidFilter);

            // ファイルのアップロード先のシークレットを取得
            KeeperRecord ownerRecord = secrets.getRecords().get(0);
        
            // アップロードするファイルからバイトを取得
            File file = new File("./myFile.json");
            FileInputStream fl = new FileInputStream(file);
            byte[] fileBytes = new byte[(int)file.length()];
            fl.read(fileBytes);
            fl.close();
            
            // アップロードするKeeperファイルを作成
            KeeperFileUpload myFile = new KeeperFileUpload(
                "myFile.json",
                "My File",
                "application/json",
                fileBytes
            )

            // 選択したレコードにファイルをアップロード
            SecretsManager.uploadFile(options, ownerRecord, myFile);
            
        } catch (Exception e) {
            System.out.println("KSM ran into an problem: " + e.getMessage());
        }
    }
}
```

### レコードからファイルを削除する <a href="#remove-files-from-a-record" id="remove-files-from-a-record"></a>

**必要なSDKバージョン:** 17.1.1以上

`UpdateOptions` クラスの `linksToRemove` パラメータを使用して、レコードからファイル添付を削除できます。

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

* ファイルを含むレコードのUID、または `KeeperRecord` オブジェクト
* 削除するファイルのファイルUID
* 削除対象のファイルがレコード上に存在していること

{% tabs %}
{% tab title="ファイルを削除" %}

<table><thead><tr><th>パラメータ</th><th width="210.44140625">型</th><th width="68.2421875">必須</th><th width="95.40625">デフォルト</th><th>説明</th></tr></thead><tbody><tr><td><code>options</code></td><td>SecretsManagerOptions</td><td>はい</td><td></td><td>事前設定されたオプション</td></tr><tr><td><code>record</code></td><td>KeeperRecord</td><td>はい</td><td></td><td>更新対象のレコード</td></tr><tr><td><code>updateOptions</code></td><td>UpdateOptions</td><td>はい</td><td></td><td>削除するファイルを含むオプション</td></tr></tbody></table>
{% endtab %}

{% tab title="UpdateOptions" %}

<table><thead><tr><th width="155.65625">パラメータ</th><th>型</th><th>必須</th><th>デフォルト</th><th>説明</th></tr></thead><tbody><tr><td><code>transactionType</code></td><td>UpdateTransactionType</td><td>いいえ</td><td><code>null</code></td><td>バッチ処理のトランザクションタイプ</td></tr><tr><td><code>linksToRemove</code></td><td>List&#x3C;String></td><td>はい</td><td></td><td>削除するファイルUIDのリスト</td></tr></tbody></table>
{% endtab %}

{% tab title="例 (Java)" %}

```java
// "temp_"で始まるファイルを削除
List<String> filesToRemove = new ArrayList<>();
for (KeeperFile file : record.getFiles()) {
    if (file.getData().getTitle().startsWith("temp_")) {
        filesToRemove.add(file.getFileUid());
    }
}

if (!filesToRemove.isEmpty()) {
    UpdateOptions updateOptions = new UpdateOptions(null, filesToRemove);
    SecretsManager.updateSecretWithOptions(options, record, updateOptions);
}
```

{% endtab %}

{% tab title="例 (Kotlin)" %}

```kotlin
// "temp_"で始まるファイルを削除
val filesToRemove = record.files
    ?.filter { it.data?.title?.startsWith("temp_") == true }
    ?.map { it.fileUid }
    ?: emptyList()

if (filesToRemove.isNotEmpty()) {
    updateSecretWithOptions(
        options,
        record,
        UpdateOptions(linksToRemove = filesToRemove)
    )
}
```

{% endtab %}
{% endtabs %}

#### 完全な使用例 <a href="#full-example-usage" id="full-example-usage"></a>

```java
import com.keepersecurity.secretsManager.core.*;
import java.util.*;

// ファイル付きのレコードを取得
QueryOptions queryOptions = new QueryOptions(
    Arrays.asList(recordUid),
    Collections.emptyList(),
    true  // ファイルをリクエスト
);

KeeperSecrets secrets = SecretsManager.getSecrets2(options, queryOptions);
KeeperRecord record = secrets.getRecords().get(0);

// 特定のファイルを削除
List<String> fileUidsToRemove = Arrays.asList("fileUid1", "fileUid2");

UpdateOptions updateOptions = new UpdateOptions(
    null,              // transactionType
    fileUidsToRemove  // linksToRemove
);

SecretsManager.updateSecretWithOptions(options, record, updateOptions);
```

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

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

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

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

```java
SecretsManager.createSecret(options, folderUid, newRecordData, secrets);
```

<table><thead><tr><th width="201">パラメータ</th><th width="230">型</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>folderUid</code></td><td>String</td><td>はい</td><td></td></tr><tr><td><code>newRecordData</code></td><td>KeeperRecordData</td><td>はい</td><td></td></tr><tr><td><code>secrets</code></td><td>KeeperSecrets</td><td>オプション</td><td>Keeperサーバーから新たに取得したすべてのシークレットのリスト</td></tr></tbody></table>
{% endtab %}

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

```java
SecretsManager.createSecret2(options, createOptions, newRecordData, folders);
```

<table><thead><tr><th width="201">パラメータ</th><th width="230">型</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>createOptions</code></td><td>CreateOptions</td><td>はい</td><td></td></tr><tr><td><code>newRecordData</code></td><td>KeeperRecordData</td><td>はい</td><td></td></tr><tr><td><code>folders</code></td><td>KeeperFolder[]</td><td>オプション</td><td>Keeperサーバーから新たに取得したすべてのフォルダのリスト</td></tr></tbody></table>
{% endtab %}

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

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

```java
import com.keepersecurity.secretsManager.core.*;

KeeperRecordData newRecordData = new KeeperRecordData(
        "Sample KSM Record:Java",
        "login",
        Arrays.asList(
                new Login("My Username"),
                new Password(CryptoUtils.generatePassword())
        ),
        null,
        "This is a \nmultiline\n\n\tnote"
);

String recordUid = SecretsManager.createSecret(options, folderUid, newRecordData);
```

{% endtab %}

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

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

```java
import com.keepersecurity.secretsManager.core.*;

KeeperRecordData newRecordData = new KeeperRecordData(
        "Sample Custom Type KSM Record:Java",
        "Custom Login",                              // レコードタイプの名前
        Arrays.asList(
                new Hosts(
                        "My Custom Host lbl",        // ラベル
                        true,                        // 必須
                        false,                       // プライベートスクリーン
                        List.of(new Host("127.0.0.1", "8000"))),
                // または new Hosts(new Host("127.0.0.1", "8000"))

                new Login("My Custom Login lbl",
                        true,
                        false,
                        List.of("login@email.com")),
                // または new Login("username@email.com")

                new Password( "My Custom Password lbl",
                        true,
                        false,
                        List.of(CryptoUtils.generatePassword())),
                // または new Password(CryptoUtils.generatePassword())

                new Url("My Login Page",
                        true,
                        false,
                        List.of("http://localhost:8080/login")),
                // または new Url("http://localhost:8080/login")
                
                new SecurityQuestions(
                        "My Question 1",
                        true,
                        false,
                        List.of(new SecurityQuestion("What is one plus one (write just a number)", "2"))),
                // または new SecurityQuestions(new SecurityQuestion("What is one plus one (write just a number)", "2"))

                new Phones("My Phone Number",
                        true,
                        false,
                        List.of(new Phone("US", "510-444-3333", "2345", "Mobile"))),
                // または new Phones(new Phone("US", "510-444-3333", "2345", "Mobile"))

                new Date("My Date Lbl",
                        true,
                        false,
                        List.of(1641934793000L)
                ),
                // または new Date(1641934793000L),

                new Names("My Custom Name lbl",
                        true,
                        false,
                        List.of(new Name("John", "Patrick", "Smith"))),
                // または new Names(new Name("John", "Patrick", "Smith"))

                new OneTimeCode("My TOTP",
                        true,
                        false,
                        List.of("otpauth://totp/Example:alice@google.com?secret=JBSWY3DPEHPK3PXP&issuer=Example"))
                // または new OneTimeCode("otpauth://totp/Example:alice@google.com?secret=JBSWY3DPEHPK3PXP&issuer=Example")
        ),
        Arrays.asList(
                new Phones(new Phone("US", "(510) 123-3456")),
                new Phones(new Phone("US", "510-111-3333", "45674", "Mobile"))
        ),
        "\tThis custom type record was created\n\tvia KSM Java Document Example"
);

String recordUid = SecretsManager.createSecret(options, "[FOLDER UID]", newRecordData);
```

{% endtab %}
{% endtabs %}

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

Java/Kotlin KSM SDKでKeeperボルトのレコードを削除できます。

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

```java
deleteSecret(smOptions, recordUids);
```

<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>recordUids</code></td><td><code>List&#x3C;Sting></code></td><td align="center">はい</td></tr></tbody></table>
{% endtab %}

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

<pre class="language-java"><code class="lang-java">// シークレットマネージャーを設定
val storage = LocalConfigStorage("ksm-config.json")
//initializeStorage(storage, "&#x3C;One Time Access Token>")
val smOptions = SecretsManagerOptions(storage)

// UIDレコードで特定のシークレットを削除
<strong>deleteSecret(smOptions, List.of("EG6KdJaaLG7esRZbMnfbFA"));
</strong></code></pre>

{% endtab %}
{% endtabs %}

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

ネットワークアクセスが失われたときにシークレットにアクセスできない状況を避けるため、Java SDKを使用してシークレットを暗号化されたファイルを使用してローカルマシンにキャッシュできます。

#### キャッシュの設定と構成 <a href="#setup-and-configure-cache" id="setup-and-configure-cache"></a>

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

Java SDKには、クエリをキャッシュしてファイルに保存するデフォルトのキャッシュ関数`cachingPostFunction` が含まれています。

```java
// キャッシュオプションを作成
SecretsManagerOptions options = new SecretsManagerOptions(storage, SecretsManager::cachingPostFunction);

// 例すべてのシークレットを取得
SecretsManager.getSecrets(options)
```

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

フォルダは完全なCRUD (作成、読み取り、更新、削除操作) をサポートしています。

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

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

```java
getFolders(options: SecretsManagerOptions): List<KeeperFolder>
```

#### レスポンス <a href="#response-4" id="response-4"></a>

型: `List<KeeperFolder>`

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

```java
import com.keepersecurity.secretsManager.core.*;
SecretsManagerOptions options = new SecretsManagerOptions(new LocalConfigStorage("ksm-config.json"));
List<KeeperFolder> folders = SecretsManager.getFolders(options);
```

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

`CreateOptions` とフォルダ名の指定が必要です。`CreateOptions` はフォルダのUIDパラメータ (共有フォルダのUID) が必須ですが、サブフォルダのUIDはオプションであり、指定されていない場合は、通常の新しいフォルダが親 (共有フォルダ) の直下に作成されます。サブフォルダは、親の共有フォルダの直接の下位オブジェクトである必要はありません。親フォルダから何階層も深い位置にサブフォルダを作成することができます。

```java
createFolder(options: SecretsManagerOptions, createOptions: CreateOptions, folderName: String, folders: List<KeeperFolder> = getFolders(options)): String
```

<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>List&#x3C;KeeperFolder></code></td><td>いいえ</td><td><code>List&#x3C;KeeperFolder></code></td><td>CreateOptionsで作成した親とサブフォルダの検索に使用するフォルダのリスト</td></tr></tbody></table>

```kotlin
data class CreateOptions  constructor(
    val folderUid:String,
    val subFolderUid:String? = null,
)
```

```kotlin
data class KeeperFolder(
    val folderKey:ByteArray,
    val folderUid:String,
    val parentUid:String? = null,
    val name:String
)
```

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

```java
import com.keepersecurity.secretsManager.core.*;
SecretsManagerOptions options = new SecretsManagerOptions(new LocalConfigStorage("ksm-config.json"));
CreateOptions co := new CreateOptions("[SHARED_FOLDER_UID]");
String folderUid = SecretsManager.createFolder(options, co, "new_folder");
```

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

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

```java
updateFolder(options: SecretsManagerOptions, folderUid: String, folderName: String, folders: List<KeeperFolder> = getFolders(options))
```

<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>List&#x3C;KeeperFolder></code></td><td>いいえ</td><td><code>List&#x3C;KeeperFolder></code></td><td>親フォルダの検索に使用するフォルダのリスト</td></tr></tbody></table>

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

```java
import com.keepersecurity.secretsManager.core.*;
SecretsManagerOptions options = new SecretsManagerOptions(new LocalConfigStorage("ksm-config.json"));
SecretsManager.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 %}

```java
deleteFolder(options: SecretsManagerOptions, folderUids: List<String>, forceDeletion: Boolean = false): SecretsManagerDeleteResponse
```

<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>List&#x3C;String></code></td><td>はい</td><td></td><td>フォルダUIDリスト</td></tr><tr><td><code>forceDeletion</code></td><td><code>Boolean</code></td><td>いいえ</td><td><code>false</code></td><td>空でないフォルダを強制的に削除</td></tr></tbody></table>

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

```java
import com.keepersecurity.secretsManager.core.*;
SecretsManagerOptions options = new SecretsManagerOptions(new LocalConfigStorage("ksm-config.json"));
SecretsManager.deleteFolder(options, Arrays.asList("[FOLDER_UID1]", "[FOLDER_UID2]"), true);
```

## PAMレコードタイプ - リンク済み認証情報へのアクセス <a href="#retrieve-records-with-relationships-graphsync" id="retrieve-records-with-relationships-graphsync"></a>

**必要なSDKバージョン:** 17.1.1以上

PAMリソースレコードタイプ (PAMマシン、PAMディレクトリ、PAMデータベース) では、以下の認証情報をリンクできます。

* **管理者認証情報**\
  リソース上で管理操作を実行するために使用される認証情報
* **接続用認証情報**\
  リソースへのセッションを起動する際の認証に使用される認証情報

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

* `getSecrets()` ではなく、`getSecrets2()` メソッドを使用すること
* `QueryOptions` で `requestLinks = true` を設定し、GraphSync™を有効化すること
* `requestLinks = false` の場合、`links` は `null` になります
* `requestLinks = true` でもリンクが存在しない場合、`links` は空のリストになります

| パラメータ          | 型                       | 必須 | デフォルト | 説明                               |
| -------------- | ----------------------- | -- | ----- | -------------------------------- |
| `options`      | `SecretsManagerOptions` | はい | なし    | 事前に構成されたオプション                    |
| `queryOptions` | `QueryOptions`          | はい | なし    | `requestLinks=true` を設定する必要があります |

#### QueryOptionsのパラメータ <a href="#queryoptions-parameters" id="queryoptions-parameters"></a>

| パラメータ           | 型              | 必須  | デフォルト   | 説明                                        |
| --------------- | -------------- | --- | ------- | ----------------------------------------- |
| `recordsFilter` | `List<String>` | いいえ | 空       | レコードUIDでフィルタリング                           |
| `foldersFilter` | `List<String>` | いいえ | 空       | フォルダUIDでフィルタリング                           |
| `requestLinks`  | `boolean`      | はい  | `false` | **GraphSyncを有効にするには `true` に設定する必要があります** |

#### リンク方式 <a href="#link-methods" id="link-methods"></a>

| メソッド                  | 戻り値       | 説明                        |
| --------------------- | --------- | ------------------------- |
| `getRecordUid()`      | `String`  | 対象レコードのUID                |
| `isAdminUser()`       | `boolean` | 管理者権限を持つ場合に `true`        |
| `allowsRotation()`    | `boolean` | ローテーションが許可されている場合に `true` |
| `allowsConnections()` | `boolean` | 接続が許可されている場合に `true`      |

#### 基本的な使い方 - リンク付きレコードの取得 <a href="#basic-usage-retrieve-records-with-links" id="basic-usage-retrieve-records-with-links"></a>

```java
import com.keepersecurity.secretsManager.core.*;
import java.util.*;

// GraphSync™ を有効化
QueryOptions queryOptions = new QueryOptions(
    Collections.emptyList(),  // recordsFilter
    Collections.emptyList(),  // foldersFilter
    true                      // requestLinks - 必須
);

SecretsManagerOptions options = new SecretsManagerOptions(storage);
KeeperSecrets secrets = SecretsManager.getSecrets2(options, queryOptions);

// リンクへアクセス
for (KeeperRecord record : secrets.getRecords()) {
    List<KeeperRecordLink> links = record.getLinks();
    if (links != null && !links.isEmpty()) {
        for (KeeperRecordLink link : links) {
            System.out.println("リンク先: " + link.getRecordUid());
        }
    }
}
```

#### リンクプロパティの確認 <a href="#check-link-properties" id="check-link-properties"></a>

```java
for (KeeperRecordLink link : record.getLinks()) {
    // ユーザー権限を確認
    if (link.isAdminUser()) {
        System.out.println("管理者ユーザー");
    }
    
    // パーミッションを確認
    if (link.allowsRotation()) {
        System.out.println("パスワードのローテーションが許可されています");
    }
}
```

#### 一般的な例 - PAMユーザーの検索 <a href="#common-example-find-pam-users" id="common-example-find-pam-users"></a>

```java
// PAMマシンに関連付けられているユーザーを検索
for (KeeperRecord machine : secrets.getRecords()) {
    if ("pamMachine".equals(machine.getType())) {
        System.out.println("PAMマシン: " + machine.getTitle());
        
        List<KeeperRecordLink> links = machine.getLinks();
        if (links != null) {
            for (KeeperRecordLink link : links) {
                // ユーザーが管理者かどうか確認
                if (link.isAdminUser()) {
                    System.out.println("  管理者ユーザー: " + link.getRecordUid());
                }
            }
        }
    }
}
```

## 追加情報 <a href="#additional-details" id="additional-details"></a>

PAMレコードタイプで取得可能なフィールドの詳細については、[レコードフィールドクラス](/keeperpam/jp/secrets-manager/developer-sdk-library/java-sdk/record-field-classes.md)のページをご参照ください。

PAMの接続設定 (RDP、SSH、VNC、Kubernetes、RBI、ポートフォワーディング) へのアクセス方法については、[Java SDKでのPAMの利用に関するページ](/keeperpam/jp/secrets-manager/developer-sdk-library/java-sdk/working-with-pam-in-java-sdk.md)をご参照ください。

高度なPAM活用事例におけるリンク済み認証情報の扱いについては、[PAMレコードのリンク済み認証情報のページ](/keeperpam/jp/secrets-manager/developer-sdk-library/java-sdk/linked-credentials-on-pam-records.md)をご覧ください。


---

# 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/java-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.
