mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-07-09 01:27:41 -07:00
address comments
This commit is contained in:
@@ -5,7 +5,7 @@ to the Gemini CLI Policy Engine.
|
||||
|
||||
## Description
|
||||
|
||||
The extension uses a `policies.toml` file to define:
|
||||
The extension uses a `policies/` directory containing `.toml` files to define:
|
||||
|
||||
- A rule that requires user confirmation for `rm -rf` commands.
|
||||
- A rule that denies searching for sensitive files (like `.env`) using `grep`.
|
||||
@@ -13,8 +13,8 @@ The extension uses a `policies.toml` file to define:
|
||||
|
||||
## Structure
|
||||
|
||||
- `gemini-extension.json`: The manifest file that points to the policy file.
|
||||
- `policies.toml`: Contains the policy rules and safety checkers.
|
||||
- `gemini-extension.json`: The manifest file.
|
||||
- `policies/`: Contains the `.toml` policy files.
|
||||
|
||||
## How to use
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"name": "policy-example",
|
||||
"version": "1.0.0",
|
||||
"description": "An example extension demonstrating Policy Engine support.",
|
||||
"policies": "policies.toml"
|
||||
"description": "An example extension demonstrating Policy Engine support."
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ import {
|
||||
applyAdminAllowlist,
|
||||
getAdminBlockedMcpServersMessage,
|
||||
CoreToolCallStatus,
|
||||
EXTENSION_POLICY_TIER,
|
||||
WORKSPACE_POLICY_TIER,
|
||||
loadPoliciesFromToml,
|
||||
PolicyDecision,
|
||||
ApprovalMode,
|
||||
@@ -761,74 +761,61 @@ Would you like to attempt to install via "git clone" instead?`,
|
||||
let rules: PolicyRule[] | undefined;
|
||||
let checkers: SafetyCheckerRule[] | undefined;
|
||||
|
||||
if (config.policies) {
|
||||
const policyPath = path.join(effectiveExtensionPath, config.policies);
|
||||
const resolvedPolicyPath = path.resolve(policyPath);
|
||||
const resolvedExtensionPath = path.resolve(effectiveExtensionPath);
|
||||
const policyDir = path.join(effectiveExtensionPath, 'policies');
|
||||
if (fs.existsSync(policyDir)) {
|
||||
const result = await loadPoliciesFromToml(
|
||||
[policyDir],
|
||||
() => WORKSPACE_POLICY_TIER,
|
||||
);
|
||||
rules = result.rules;
|
||||
checkers = result.checkers;
|
||||
|
||||
if (!resolvedPolicyPath.startsWith(resolvedExtensionPath)) {
|
||||
debugLogger.warn(
|
||||
`[ExtensionManager] Extension "${config.name}" attempted to contribute a policy file outside its directory: "${config.policies}". Ignoring for security.`,
|
||||
);
|
||||
} else if (fs.existsSync(policyPath)) {
|
||||
const result = await loadPoliciesFromToml(
|
||||
[policyPath],
|
||||
() => EXTENSION_POLICY_TIER,
|
||||
);
|
||||
rules = result.rules;
|
||||
checkers = result.checkers;
|
||||
|
||||
// Prefix source with extension name to avoid collisions
|
||||
if (rules) {
|
||||
rules = rules.filter((rule) => {
|
||||
// Security: Extensions are not allowed to automatically approve tool calls.
|
||||
// We ignore any rule that is ALLOW.
|
||||
if (rule.decision === PolicyDecision.ALLOW) {
|
||||
debugLogger.warn(
|
||||
`[ExtensionManager] Extension "${config.name}" attempted to contribute an ALLOW rule for tool "${rule.toolName}". Ignoring this rule for security.`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Security: Extensions are not allowed to contribute YOLO mode rules.
|
||||
if (rule.modes?.includes(ApprovalMode.YOLO)) {
|
||||
debugLogger.warn(
|
||||
`[ExtensionManager] Extension "${config.name}" attempted to contribute a rule for YOLO mode. Ignoring this rule for security.`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
rule.source = `Extension (${config.name}): ${rule.source}`;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
if (checkers) {
|
||||
checkers = checkers.filter((checker) => {
|
||||
// Security: Extensions are not allowed to contribute YOLO mode checkers.
|
||||
if (checker.modes?.includes(ApprovalMode.YOLO)) {
|
||||
debugLogger.warn(
|
||||
`[ExtensionManager] Extension "${config.name}" attempted to contribute a safety checker for YOLO mode. Ignoring this checker for security.`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
checker.source = `Extension (${config.name}): ${checker.source}`;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
if (result.errors.length > 0) {
|
||||
for (const error of result.errors) {
|
||||
// Prefix source with extension name to avoid collisions
|
||||
if (rules) {
|
||||
rules = rules.filter((rule) => {
|
||||
// Security: Extensions are not allowed to automatically approve tool calls.
|
||||
// We ignore any rule that is ALLOW.
|
||||
if (rule.decision === PolicyDecision.ALLOW) {
|
||||
debugLogger.warn(
|
||||
`[ExtensionManager] Error loading policies from ${config.name}: ${error.message}`,
|
||||
`[ExtensionManager] Extension "${config.name}" attempted to contribute an ALLOW rule for tool "${rule.toolName}". Ignoring this rule for security.`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Security: Extensions are not allowed to contribute YOLO mode rules.
|
||||
if (rule.modes?.includes(ApprovalMode.YOLO)) {
|
||||
debugLogger.warn(
|
||||
`[ExtensionManager] Extension "${config.name}" attempted to contribute a rule for YOLO mode. Ignoring this rule for security.`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
rule.source = `Extension (${config.name}): ${rule.source}`;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
if (checkers) {
|
||||
checkers = checkers.filter((checker) => {
|
||||
// Security: Extensions are not allowed to contribute YOLO mode checkers.
|
||||
if (checker.modes?.includes(ApprovalMode.YOLO)) {
|
||||
debugLogger.warn(
|
||||
`[ExtensionManager] Extension "${config.name}" attempted to contribute a safety checker for YOLO mode. Ignoring this checker for security.`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
checker.source = `Extension (${config.name}): ${checker.source}`;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
if (result.errors.length > 0) {
|
||||
for (const error of result.errors) {
|
||||
debugLogger.warn(
|
||||
`[ExtensionManager] Error loading policies from ${config.name}: ${error.message}`,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
debugLogger.warn(
|
||||
`[ExtensionManager] Policy file not found for ${config.name}: ${policyPath}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,10 +33,6 @@ export interface ExtensionConfig {
|
||||
* These themes will be registered when the extension is activated.
|
||||
*/
|
||||
themes?: CustomTheme[];
|
||||
/**
|
||||
* Path to a policy TOML file relative to the extension root.
|
||||
*/
|
||||
policies?: string;
|
||||
}
|
||||
|
||||
export interface ExtensionUpdateInfo {
|
||||
|
||||
Reference in New Issue
Block a user