本番環境への準備
セルフマネージドの ObjectOS デプロイメントを本番で安全に実行するためのチェックリストです。ヘッダー、シークレット、レート制限、CORS、起動時のガード、スケジュールされた処理、保持期間を扱います。
ObjectOS を本番トラフィックに公開する前に、このチェックリストを使ってください。Community にも Enterprise にも当てはまります。最後の Enterprise で追加されるもののセクションには、ライセンスされたイメージに伴う項目を挙げています。
HTTP の堅牢化
ランタイムは、デフォルトでルートに保守的なセキュリティヘッダーを送信します。ヘッダーを書き換えるプロキシを通った後の、最終的なレスポンスを確認してください。
Content-Security-PolicyX-Content-Type-OptionsX-Frame-OptionsReferrer-PolicyPermissions-PolicyCross-Origin-Resource-Policy- HSTS。ランタイムはデフォルトでは送信しません。TLS を確認してからプロキシで追加してください。
curl -I https://app.example.comシークレット
これらはシークレットマネージャーに保管し、実行時に注入します。
| シークレット | 目的 |
|---|---|
OS_AUTH_SECRET | セッション署名の基本シークレット。すべてのレプリカで同一にします。値の異なるレプリカは互いのセッションを拒否します。 |
OS_SECRET_KEY | 保存されたすべてのシークレットを暗号化するキー。自己生成したキーがファイルシステムとともに消えるコンテナでは必須です。データベースと一緒にバックアップしてください。一方だけでは何も復号できません。 |
| データベースの認証情報 | 業務データベースへのアクセス |
| OIDC クライアントシークレット | シングルサインオン |
| プロバイダーの API キー | メール、ストレージ、AI、連携 |
シークレットをアーティファクトやイメージに焼き込まないでください。
コントロールプレーンにバインドされたデプロイメントはランタイムトークンも保持しますが、それは設定するシークレットではありません。バインディングの際に発行され、ランタイムが永続化します。そのために配布するデプロイメントレベルの API キーはありません。
レート制限
ランタイムには組み込みのトークンバケット方式のレート制限があり、アプリが予算を宣言するまでオフです(スタックの server.security.rateLimit)。予算を超えた呼び出し元には、Retry-After 付きの 429 が返されます。バケットのキーは、サインインしたユーザー、匿名のトラフィックでは呼び出し元のアドレスです。
リバースプロキシの背後では、アプリが server.trustProxy: true を設定しない限り、呼び出し元のアドレスはプロキシのものになります。これは、すべてのリクエストで X-Forwarded-For を上書きするプロキシの背後でだけ設定してください。そうでなければ、呼び出し元が自分のアドレスを選べてしまいます。カウンターはプロセスごとにメモリ内に保持されます。サインインには、Setup → Authentication で、より厳しい専用の予算を設定できます。
制限を代わりにエッジ(イングレスやゲートウェイ)に置く場合は、次のような予算から始めてください。
| トラフィック | 制限の例 |
|---|---|
| 認証エンドポイント | 10/分/IP |
| 書き込みリクエスト | 60/分/IP |
| 読み取りリクエスト | 600/分/IP |
CORS
OS_CORS_ORIGIN がない場合、ランタイムはクロスオリジンの呼び出し元を一切受け入れません。Console と API が同じ公開オリジンを共有している間は、それで問題ありません。別のオリジンから提供されるフロントエンドは、カンマ区切りで明示的に列挙します。
OS_CORS_ORIGIN=https://portal.example.com,https://admin.example.com認証情報が有効な間、* は起動時に拒否されます。
起動時のガードはオンのままにする
開発用に 2 つの抜け道があります。どちらも本番には不適切です。
OS_ALLOW_DRIVER_CONNECT_FAILUREは未設定にします。 起動時に接続できないデータベースは起動を拒否するため、誤ったOS_DATABASE_URL、ローテーションされたパスワード、閉じたネットワーク経路はデプロイの失敗になります。すべてのリクエストに 500 を返す「起動済み」のサーバーにはなりません。このフラグはデータベースなしで起動し、再接続することはありません。OS_ALLOW_DEGRADED_TENANCYは未設定にします。 組織のランタイムなしで複数の組織を求めるデプロイメントは起動を拒否します。このフラグは、分離が欠けたまま起動させてしまいます。
スケジュールされた処理は判断である
アプリやパッケージが宣言するスケジュールされた処理(時間で起動するフローとパッケージ化された cron ジョブ)は、デプロイメントが OS_AUTOMATION_SCHEDULED_WORK_ENABLED=true を設定するまでオフです。ダイジェスト、スイープ、リマインダーの起動を期待するデプロイメントは、これをオンにする必要があります。オフのままにするのも正当な答えです。意図して決めてください。実効値は os doctor で確認し、起動時のサマリーを読んでください。そこに disabled by deployment policy と表示される処理は壊れているのではなく、オフになっているだけです。環境変数を参照してください。
保持期間は本番稼働前に設定する
プラットフォームはテレメトリをスケジュールに従って削除します。アクティビティは 14 日後、ジョブの実行は 30 日後、通知は 90 日後、監査レコードは 90 日後にホットストレージから外れます。コンプライアンス上より長い期間が必要な場合は、本番稼働の前に lifecycle.retention_overrides 設定で期間を延長してください。ポリシーによって削除されたデータは、その後に取得するすべてのバックアップから消えています。
本番稼働のチェックリスト
- TLS がエッジまたはイングレスで終端されている。
- 最終的なレスポンスにセキュリティヘッダーが含まれている。
- TLS の検証後に HSTS が有効になっている。
-
OS_AUTH_URLとOS_TRUSTED_ORIGINSが公開アドレスと一致している。 - CORS が、提供するクロスオリジンのフロントエンドだけを正確に受け入れている。
- レート制限がサインインと書き込みのエンドポイントを保護している。
-
OS_AUTH_SECRETとOS_SECRET_KEYが強力で、シークレットとして保管され、預託されている。 - アドレスを共有する前に、最初の管理者が登録されている。
- OIDC のコールバック URL が公開ドメインと一致している。
-
OS_ALLOW_DRIVER_CONNECT_FAILUREとOS_ALLOW_DEGRADED_TENANCYが未設定である。 -
OS_AUTOMATION_SCHEDULED_WORK_ENABLEDが、誰かが下した判断になっている。 - 保持期間がポリシーと一致している。
- 業務データベースのバックアップと復元がテストされている。バックアップを参照。
- 監査ログがポリシーに従って保持されている。
- 監視が 5xx の割合と readiness でアラートを出す。オブザーバビリティを参照。
- ロールバック計画が、イメージのバージョンとアプリのアーティファクトのバージョンの両方を対象にしている。
Enterprise で追加されるもの
-
OS_LICENSE_KEY(デプロイメントのエンタイトルメント)がシークレットとして保管されている。 -
OS_CLOUD_URLが宣言され、ライセンスモードと一致している。通常のライセンスとoffの組み合わせは起動時に拒否されます。エアギャップを参照。 - イメージがダイジェストで固定され、その署名、SBOM、来歴が検証されている(Docker)。
- 複数のレプリカでは、
OS_AUTH_SECRETとOS_SECRET_KEYがすべてのレプリカで同一である。 - マルチ組織の姿勢では、メンバーシップのポリシーとマウントする AI エージェントが宣言され、
OS_PLATFORM_OWNER_EMAILが確認済みの管理者を 2 人以上指定し、組織をまたぐアクセスの否定テストが合格している。