gog-safe
v0.1.6
Published
Policy-enforced wrapper for gog
Readme
gog-safe
gog-safe は gog 用の安全ラッパーCLIです。
policy ベースで Gmail / Sheets コマンドを制御し、必要に応じてコマンド別の後処理バリデーションを実行します。
Install
npm install -g gog-safeインストール後:
gog-safe versionQuick Start
policy.ymlを作成:
version: 1
gog:
binary: gog
client: ""
execution:
enforce_json: true
enforce_no_input: true
timeout_ms: 30000
commands:
allow:
- "sheets get"
- "gmail thread get"
deny:
- "gmail send"
- "gmail delete"
validation:
rules:
- match: "sheets get"
validators: ["llm-guard"]
validators:
llm-guard:
type: external_command
command: node
args: ["./scripts/validator.mjs"]
timeout_ms: 60000
logging:
level: info
audit_file: "./gog-safe-audit.log"
require_audit_success: falseconfig.jsonに profile を定義:
./.gog-safe/config.json
{
"gog": {
"profiles": {
"work": { "account": "[email protected]" }
}
}
}- policy 検証:
gog-safe validate-policy --policy ./policy.yml- 実行:
gog-safe run --policy ./policy.yml --profile work -- sheets get --range A1:B2CLI
gog-safe run [--policy <path>] --profile <name> -- <gog args...>
gog-safe validate-policy [--policy <path>]
gog-safe print-effective-policy [--policy <path>]
gog-safe profile-list
gog-safe list-profiles
gog-safe docs
gog-safe versionprofile-list(list-profiles 互換)は、現在ディレクトリから親へ探索した project 設定と ~/.gog-safe/config.json を反映した有効 profile 一覧を表示し、その下に gog auth list --check の実行結果をそのまま表示します。
Safety Model
runは常に統一JSONを返します(成功/失敗共通)。- バリデータ障害(timeout / 非JSON / exit!=0 / 契約不正)は fail-closed(
block,ok:false)。 - 監査ログ書き込み失敗はデフォルト fail-open(
require_audit_success:false)。 require_audit_success:trueの場合、監査ログ失敗も fail-closed。- 最終可否は
safety.actionとokを参照してください。 allowedは allow/deny 判定のみを表し、validator 結果は含みません。
Config Discovery
次の順で読み込み・マージします:
policy.yml(run/validate-policy/print-effective-policyで利用)--policy指定時: 明示パスを使用--policy未指定時:~/.gog-safe/policy.yml→./.gog-safe/policy.ymlの順に探索- どちらにも無ければエラー
~/.gog-safe/config.json(任意)- カレントディレクトリから親へ探索して最初に見つかった
.gog-safe/config.json(任意)
policy.yml での gog.account / gog.profiles 指定は非対応です。profile は config.json の gog.profiles で定義します。
Merge Rules
commands.allow: 上書き優先(project > home > policy)commands.deny: 和集合(policy ∪ home ∪ project)validation.rules: 連結(policy + home + project)validation.validators: キー単位上書き(project > home > policy)gog.profiles:homeを基準に、projectがあれば全置換gog.binary/gog.client/execution/logging: キー単位上書き(project > home > policy)
Run Behavior
run 実行時に以下を強制します:
--json(execution.enforce_json=trueの場合)--no-input(execution.enforce_no_input=trueの場合)--account=<gog.profiles[--profile].account>--client=<gog.client>(gog.clientが非空の場合のみ)
ユーザーが --json / --no-input / --account / --client(--k=v 含む)を指定した場合は拒否します。validation.rules.match は強制フラグ付与前のユーザー argv に対して評価します。
--profile は run で必須です。未指定または未定義 profile は block(終了コード 2)になります。
v1 ではコマンドオプション自体の妥当性バリデーション(値の正当性チェックなど)は行いません。
Validator Contract (external_command)
stdin:
{
"command": "gog sheets get --range A1:B2",
"argv": ["sheets", "get", "--range", "A1:B2"],
"output": {"...": "..."},
"policy_version": 1
}stdout:
{
"decision": "allow",
"reason": "safe"
}ルール:
decisionはallowまたはblockreasonは文字列必須(blockは非空必須、allowは空文字許容)- timeout / 非JSON / exit!=0 / 契約不正は
block - 複数validatorは OR-block(1つでも
blockで停止)
Multiple Rule Matches
1つのコマンドに複数の validation.rules が同時にマッチした場合:
rulesを定義順に走査- マッチした各 rule の
validatorsを配列連結 - validator 名を重複排除(最初に出た順序は維持)
- その順で実行し、1つでも
blockが出たら停止
Output Schema (run)
{
"ok": true,
"allowed": true,
"command": "gog sheets get",
"safety": {
"action": "allow",
"reasons": []
},
"data": {},
"meta": {
"policy_version": 1
}
}gog の出力は JSON object である必要があります(スカラー/配列はエラー扱い)。
Audit Logging Details
logging.require_audit_success=false(デフォルト):- 監査ログ書き込み失敗でも実行継続(fail-open)
safety.reasonsにaudit_log_write_failedを追加- stderr に警告を出力
logging.require_audit_success=true:- 監査ログ書き込み失敗で
block+ok:false(fail-closed)
- 監査ログ書き込み失敗で
runは監査ログの成否を確定してから最終JSONを返します。
Exit Codes (run)
0: 最終許可(ok:true)2: policy/validator による block(fail-closed 含む)3: runtime/system error(spawn失敗、timeout、非0終了、非JSON、スキーマ不正など)
Operational Examples
1) gmail labels * を project 側で拒否
policy.yml:
commands:
allow:
- "gmail labels *"<project>/.gog-safe/config.json:
{
"commands": {
"deny": ["gmail labels *"]
}
}deny 優先のため、このプロジェクトでは gmail labels 系は拒否されます。
2) 端末共通 allow を、特定プロジェクトで上書き
~/.gog-safe/config.json:
{
"commands": {
"allow": ["gmail thread get", "sheets get"]
}
}<project>/.gog-safe/config.json:
{
"commands": {
"allow": ["sheets metadata"]
}
}commands.allow は上書き優先のため、当該プロジェクトで有効なのは ["sheets metadata"] です。
3) sheets get だけ追加バリデーション
validation:
rules:
- match: "sheets get"
validators: ["llm-guard"]
validators:
llm-guard:
type: external_command
command: node
args: ["./scripts/validator.mjs"]
timeout_ms: 60000この設定では sheets get 実行時のみ llm-guard が実行され、他コマンドは未マッチなら追加検査されません。
4) profile の使い分け(project 側で全置換)
~/.gog-safe/config.json:
{
"gog": {
"profiles": {
"work": { "account": "[email protected]" },
"personal": { "account": "[email protected]" }
}
}
}<project>/.gog-safe/config.json:
{
"gog": {
"profiles": {
"project-work": { "account": "[email protected]" }
}
}
}project に gog.profiles がある場合、home 側 profiles は引き継がれず project 側で全置換されます。
