はじめに
ゼロから、ポリシーで解決される最初の暗号処理まで — Java と .NET で。
前提条件
- Enterprise または Free Trial エディションの DuoKey Cockpit テナント(cap.enabled 機能)。
- JDK 17 以上(Java)または .NET 6 以上(.NET)。
- 一度限りのポリシー / 鍵のセットアップ用: Cockpit 管理者セッション(以下の 2 つのアクセスモデルを参照)。
2 つのアクセスモデル
CAP には2 つのプレーンがあり、それぞれ認証方法が異なります。用途に応じて適切な方を 使用してください。
| プレーン | 利用者 | 認証 | エンドポイント |
|---|---|---|---|
| コントロールプレーン | セキュリティ / プラットフォームチーム(一度だけ) | Cap.* 権限を持つ Cockpit セッション(JWT) | /api/cap/policies, /api/cap/policies/from-template, /api/cap/policy-templates, /api/cap/simulate, /api/cap/drift, /api/cap/sdk/keys |
| データプレーン(SDK) | アプリケーション(リクエストごと) | CAP API キー dke_cap_… | /api/cap/sdk/resolve, /api/cap/sdk/observe |
dke_cap_… キーは、データプレーンの /api/cap/sdk/* ルートでのみ受け付けられます。
ポリシーとテンプレートの管理には、Cap.Policies.Manage を持つ Cockpit セッションを使用します。
ステップ 1 — テナントポリシーをブートストラップする
セキュリティチームは、ルールを手作業で作成する代わりに、組み込みのコンプライアンス
テンプレートから始めます。これはコントロールプレーンの呼び出しです(Cockpit セッション、Cap.Policies.Manage)。
curl -X POST "https://cockpit.example.com/api/cap/policies/from-template" \
-H "Authorization: Bearer $COCKPIT_SESSION_JWT" \
-H "Content-Type: application/json" \
-d '{ "template_key": "pci_dss_4", "name": "PCI baseline" }'テンプレート: pci_dss_4、finma_ch、enisa_eu、cnsa_2_0、fips_fedramp、
gdpr_pii(GET /api/cap/policy-templates で一覧を取得できます)。それぞれが何にマッピング
されるかはインテントとポリシーを参照してください。
CAP は、テナントのアクティブなポリシー — 有効化されている最新のポリシー
(version が最大のもの) — に対して解決します。ただしリクエストが特定の policy_id を
指定している場合を除きます。その場での編集はできません。ルールを変更するには、新しい
(より高いバージョンの)ポリシーを作成します。
ステップ 2 — SDK キーを発行する
アプリケーションは CAP API キーで認証します(コントロールプレーンの呼び出し、
Cap.Sdk.Manage)。平文は一度だけ表示されるため、シークレットマネージャーに保管してください。
curl -X POST "https://cockpit.example.com/api/cap/sdk/keys" \
-H "Authorization: Bearer $COCKPIT_SESSION_JWT" \
-H "Content-Type: application/json" \
-d '{ "name": "payments-svc" }'
# → { "id": "...", "key": "dke_cap_ab12cd34_<48 random chars>", ... }シークレットストアまたは環境変数(例: CAP_KEY)から注入してください。dke_cap_… キーを
リポジトリにコミットしないでください。
ステップ 3 — リファレンスクライアントを入手する
CAP は、Cockpit からダウンロードしてプロジェクトに配置できる軽量なリファレンスクライアントを
提供しています。ダウンロードエンドポイントは JSON エンベロープ(language、filename、
content)を返すため、レスポンスボディをそのまま保存するのではなく、content フィールドを
— 例えば jq で — 抽出してください。
# Java
curl -H "Authorization: Bearer $COCKPIT_SESSION_JWT" \
"https://cockpit.example.com/api/cap/sdk/download/java" \
| jq -r '.content' > CapClient.java
# .NET
curl -H "Authorization: Bearer $COCKPIT_SESSION_JWT" \
"https://cockpit.example.com/api/cap/sdk/download/dotnet" \
| jq -r '.content' > CapClient.csリファレンスクライアントは node、python、go、php、cobol 向けにも用意されています。
ステップ 4 — 最初の resolve と observe
インテントを resolve する
データクラス+目的に対して何を実行すべきかを CAP に問い合わせます。アルゴリズム、 耐量子ポスチャ、鍵参照、バックエンドクラスが返されます。
処理を実行する
解決されたアルゴリズムと、ポリシーが参照する鍵を使って処理を実行します。
実行内容を observe する
CAP がドリフトを検出できるよう、実際に実行されたアルゴリズムを報告します。
Java
import ch.duokey.cap.CapClient;
import ch.duokey.cap.CapClient.CapDecision;
var cap = new CapClient("https://cockpit.example.com/api", System.getenv("CAP_KEY"));
CapDecision d = cap.resolve("pii", "sign");
System.out.println(d.algorithm()); // hybrid-ml-dsa65-ecdsa-p256
System.out.println(d.posture()); // hybrid
System.out.println(d.quantumResistant()); // true
System.out.println(d.backend()); // pqc_capable
// ... run the signature with d.algorithm() using the policy-referenced key ...
cap.observe("pii", "sign", "ecdsa-p256", "payments-svc");.NET
using DuoKey.Cap;
var cap = new CapClient("https://cockpit.example.com/api", Environment.GetEnvironmentVariable("CAP_KEY"));
CapDecision d = await cap.ResolveAsync("pii", "sign");
Console.WriteLine(d.Algorithm); // hybrid-ml-dsa65-ecdsa-p256
Console.WriteLine(d.Posture); // hybrid
Console.WriteLine(d.QuantumResistant); // True
Console.WriteLine(d.Backend); // pqc_capable
// ... run the signature with d.Algorithm using the policy-referenced key ...
await cap.ObserveAsync("pii", "sign", "ecdsa-p256", "payments-svc");セキュリティチームがポリシーを耐量子のみに引き上げても、このコードは変更されません。
次回の resolve(...) が単に ml-dsa65 を返すようになります。