Application des politiques aux actions des agents
Vérifications des politiques avant action, listes d’autorisation et d’interdiction, et règles de politique dynamiques.
Application des politiques aux actions des agents est une leçon AI Agents gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage AI Agents, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours AI Agents comprend 4 leçons au total.
Qu'est-ce que l'application des politiques de l'agent ?
L'application des politiques est le point de contrôle à l'exécution qui s'active avant chaque action de l'agent afin de décider si celle-ci est autorisée. Sans ce contrôle, la seule contrainte de l'agent est son respect des instructions du LLM — un respect qui peut être contourné ou mal interprété.
L'application des politiques doit se trouver en dehors du LLM, dans votre infrastructure.
Schéma de vérification avant action
Avant d'exécuter un outil, appelez can_agent_do(action, context). Cette fonction est l'unique point d'application des politiques : tout chemin menant à l'exécution d'une action doit passer par elle.
def can_agent_do(action: str, context: dict) -> tuple[bool, str]:
'''
Returns (allowed: bool, reason: str).
Context includes: user_id, agent_id, session_id, parameters, timestamp.
'''
# 1. Check denylist first (fast path for obvious violations)
if action in DENIED_ACTIONS:
return False, f'Action "{action}" is on the global denylist'
# 2. Check allowlist
if action not in ALLOWED_ACTIONS:
return False, f'Action "{action}" is not on the allowlist'
# 3. Context-specific checks
return check_context_policy(action, context)Définir des listes d'autorisation et de refus
La liste d'autorisation énumère toutes les actions que l'agent est autorisé à effectuer. Tout ce qui ne figure pas dans la liste est bloqué par défaut. La liste de refus ajoute un niveau de sécurité pour les actions qui ne doivent jamais être autorisées, quel que soit le contexte.
# Allowlist: tools the agent can use
ALLOWED_ACTIONS = {
'web_search',
'read_file',
'write_file',
'send_email',
'create_calendar_event',
'query_database',
'execute_python_sandbox',
'fetch_url',
'create_ticket'
}
# Denylist: actions that are always blocked, regardless of context
DENIED_ACTIONS = {
'delete_all_records',
'export_entire_database',
'send_mass_email',
'modify_system_config',
'create_admin_user',
'disable_audit_logging'
}
if __name__ == '__main__':
for action in ('web_search', 'send_mass_email'):
print(f"{action}: allowed={action in ALLOWED_ACTIONS} denied={action in DENIED_ACTIONS}")
Vérifications des politiques selon le contexte
Au-delà des simples listes d'autorisation et de refus, les politiques dépendent souvent du contexte : qui est l'utilisateur, quel est son rôle, quelle heure est-il et quelle est la ressource cible ? Ce sont des vérifications propres au contexte.
from datetime import datetime, timezone
def check_context_policy(action: str, context: dict) -> tuple[bool, str]:
user_id = context.get('user_id', '')
params = context.get('parameters', {})
user_role = context.get('user_role', 'user')
# send_email: only agents with email_sender role
if action == 'send_email':
if user_role not in ('email_agent', 'admin'):
return False, f'Role "{user_role}" cannot send emails'
recipient = params.get('to', '')
if not recipient.endswith('@trusted-domain.com'):
return False, 'Email recipient must be in @trusted-domain.com'
# write_file: path restrictions
if action == 'write_file':
path = params.get('path', '')
if not path.startswith('/tmp/') and not path.startswith('/workspace/'):
return False, f'File writes outside /tmp/ and /workspace/ are not allowed'
return True, 'Permitted'
if __name__ == '__main__':
ctx = {'user_id': 'u1', 'user_role': 'user',
'parameters': {'to': 'someone@gmail.com'}}
print('send_email as user:', check_context_policy('send_email', ctx))
ctx2 = {'user_id': 'u1', 'user_role': 'user',
'parameters': {'path': '/etc/passwd'}}
print('write_file outside sandbox:', check_context_policy('write_file', ctx2))
Politiques dynamiques provenant d'un moteur de politiques
Les politiques inscrites en dur sont difficiles à mettre à jour en production. Utilisez un moteur de politiques (tel que OPA — agent de politiques ouvert) pour évaluer des politiques définies comme des données plutôt que comme du code. Les politiques peuvent ainsi être mises à jour sans redéployer l'agent.
import requests
OPA_URL = 'http://localhost:8181/v1/data/agent/allow'
def opa_policy_check(action: str, context: dict) -> tuple[bool, str]:
payload = {
'input': {
'action': action,
'user_id': context.get('user_id'),
'role': context.get('user_role', 'user'),
'params': context.get('parameters', {}),
'time_utc': datetime.now(timezone.utc).isoformat()
}
}
try:
resp = requests.post(OPA_URL, json=payload, timeout=0.5)
result = resp.json().get('result', {})
allowed = result.get('allow', False)
reason = result.get('reason', 'Policy decision')
return allowed, reason
except Exception as e:
# Fail closed: deny if policy engine is unreachable
return False, f'Policy engine unavailable: {e}'Refus par défaut ou autorisation par défaut
Lorsque le moteur de politiques est indisponible, deux possibilités s'offrent à vous :
- Refus par défaut : refuser toutes les actions. C'est sûr, mais l'agent cesse de fonctionner.
- Autorisation par défaut : autoriser toutes les actions. L'agent continue de fonctionner, mais la politique n'est pas appliquée.
Pour les agents traitant des données sensibles, choisissez toujours le refus par défaut. Pour les agents de productivité qui effectuent des actions à faible risque, l'autorisation par défaut peut être acceptable.
FAIL_CLOSED = True # Configure per agent
def safe_policy_check(action: str, context: dict) -> tuple[bool, str]:
try:
return can_agent_do(action, context)
except Exception as e:
if FAIL_CLOSED:
return False, f'Policy check failed (fail-closed): {e}'
else:
# Log the failure but allow the action
import logging
logging.warning('Policy check error (fail-open): %s', e)
return True, 'Policy check bypassed due to error (fail-open)'Limiter la fréquence des actions
L'application des politiques peut inclure des limites de fréquence : un agent peut être autorisé à envoyer des courriels, mais seulement 5 par session. Si la limite est dépassée, l'action est refusée.
from collections import defaultdict
import time
action_counts: dict[str, dict[str, int]] = defaultdict(lambda: defaultdict(int))
action_window_start: dict[str, float] = defaultdict(float)
ACTION_RATE_LIMITS = {
'send_email': {'limit': 5, 'window_secs': 3600}, # 5/hour
'write_file': {'limit': 50, 'window_secs': 300},
'web_search': {'limit': 20, 'window_secs': 60}
}
def check_rate_limit(action: str, session_id: str) -> tuple[bool, str]:
limit_config = ACTION_RATE_LIMITS.get(action)
if not limit_config:
return True, 'No rate limit defined'
window = limit_config['window_secs']
now = time.time()
key = f'{session_id}:{action}'
if now - action_window_start[key] > window:
action_counts[key] = defaultdict(int)
action_window_start[key] = now
action_counts[key]['count'] += 1
if action_counts[key]['count'] > limit_config['limit']:
return False, f'Rate limit exceeded: {action} ({limit_config["limit"]}/{window}s)'
return True, 'Within rate limit'
if __name__ == '__main__':
for i in range(6):
allowed, reason = check_rate_limit('send_email', 'session-1')
print(f'After 6 send_email calls: allowed={allowed}, reason={reason}')
Journaliser les violations de politique
Chaque refus fondé sur une politique doit être journalisé avec son contexte complet. Ces journaux sont le premier endroit à consulter pour déboguer un comportement inattendu de l'agent ou enquêter sur un incident de sécurité.
import logging, json, time
policy_logger = logging.getLogger('agent.policy')
def enforced_action(agent_id: str, user_id: str, action: str,
context: dict, audit_log) -> tuple[bool, str]:
allowed, reason = safe_policy_check(action, context)
log_entry = {
'ts': time.time(),
'agent_id': agent_id,
'user_id': user_id,
'action': action,
'allowed': allowed,
'reason': reason,
'params': context.get('parameters', {})
}
if allowed:
policy_logger.info('ALLOWED %s', json.dumps(log_entry))
else:
policy_logger.warning('DENIED %s', json.dumps(log_entry))
audit_log.append(
agent_id, user_id,
f'POLICY_{"ALLOW" if allowed else "DENY"}',
{'action': action},
{'allowed': allowed, 'reason': reason},
context.get('session_id', '')
)
return allowed, reasonDélimiter les ressources
Même pour les actions autorisées, limitez les ressources auxquelles l'agent peut accéder. Un agent qui traite les documents de l'utilisateur A ne doit pas pouvoir lire les fichiers de l'utilisateur B, même si read_file figure dans la liste d'autorisation.
def check_resource_scope(action: str, context: dict) -> tuple[bool, str]:
user_id = context.get('user_id', '')
params = context.get('parameters', {})
if action == 'read_file':
path = params.get('path', '')
# Each user's files must be under their own namespace
if not path.startswith(f'/workspace/{user_id}/'):
return False, (
f'User {user_id} cannot read files outside '
f'/workspace/{user_id}/'
)
if action == 'query_database':
table = params.get('table', '')
allowed_tables = {'products', 'public_docs', f'user_{user_id}_data'}
if table not in allowed_tables:
return False, f'Table "{table}" not in scope for user {user_id}'
return True, 'Resource scope check passed'
if __name__ == '__main__':
ctx = {'user_id': 'u1', 'parameters': {'path': '/workspace/u2/secret.txt'}}
print('Cross-user file read:', check_resource_scope('read_file', ctx))
ctx2 = {'user_id': 'u1', 'parameters': {'path': '/workspace/u1/notes.txt'}}
print('Own file read: ', check_resource_scope('read_file', ctx2))
Évaluer les règles de politique
Les règles de politique sont du code : elles doivent être vérifiées. Écrivez des évaluations unitaires pour chaque règle afin de vous assurer que les refus et les autorisations fonctionnent correctement et que les cas limites n'entraînent pas de contournements accidentels des politiques.
def test_policy_rules():
# Denylist blocks unconditionally
ok, msg = can_agent_do('delete_all_records', {'user_role': 'admin'})
assert not ok, 'Denylist should block even for admin'
# Email requires trusted domain
ok, msg = can_agent_do('send_email', {
'user_role': 'email_agent',
'parameters': {'to': 'attacker@evil.com'}
})
assert not ok, 'Should block untrusted email recipient'
# File write outside allowed paths
ok, msg = can_agent_do('write_file', {
'user_role': 'user',
'parameters': {'path': '/etc/crontab'}
})
assert not ok, 'Should block write to /etc/'
print('All policy tests passed')
test_policy_rules()Mettre en cache les décisions de politique
Appeler le moteur de politiques pour chaque action ajoute de la latence, surtout lorsqu'un service OPA externe est utilisé. Mettez en cache les décisions récentes pour les paires constituées de l'action et de l'empreinte du contexte, avec un TTL court, afin de réduire les allers-retours.
import hashlib, time
policy_cache: dict[str, dict] = {}
POLICY_CACHE_TTL = 10 # seconds — short TTL so policy updates take effect quickly
def cached_policy_check(action: str, context: dict) -> tuple[bool, str]:
ctx_hash = hashlib.md5(
f'{action}:{context.get("user_id")}:{context.get("user_role")}'
.encode()
).hexdigest()
key = f'{action}:{ctx_hash}'
entry = policy_cache.get(key)
if entry and time.time() - entry['ts'] < POLICY_CACHE_TTL:
return entry['result']
result = can_agent_do(action, context)
policy_cache[key] = {'result': result, 'ts': time.time()}
return resultQuelle est l'approche du refus par défaut pour l'application des politiques ?
Le choix entre le refus par défaut et l'autorisation par défaut constitue un compromis fondamental en matière de sécurité pour tout système d'application des politiques. Savoir quand chacune de ces approches est appropriée est un concept essentiel de gouvernance.
Récapitulatif de l'application des politiques
L'application des politiques d'un agent utilise : une vérification avant action comme point de contrôle unique, des listes d'autorisation et de refus pour les décisions de base, des règles propres au contexte pour délimiter les ressources et vérifier les rôles, un moteur de politiques dynamique (OPA) pour mettre à jour les règles, des limites de fréquence par action et par session, ainsi que le refus par défaut pour les agents dont la sécurité est critique.
Apprends AI Agents avec un tuteur IA — gratuit
Écris et exécute du vrai code dans ton navigateur, obtiens de l'aide instantanée d'un tuteur IA disponible 24h/24, et reprends là où tu t'es arrêté sur le web ou dans l'app.
- Cours
- 60
- Leçons
- 239
Questions Fréquemment Posées
La leçon « Application des politiques aux actions des agents » est-elle gratuite ?
Oui — le texte complet de « Application des politiques aux actions des agents » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours AI Agents, passe à CoddyKit PRO. Le cours AI Agents comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Application des politiques aux actions des agents » ?
Vérifications des politiques avant action, listes d’autorisation et d’interdiction, et règles de politique dynamiques. Tu pratiques AI Agents avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer AI Agents ?
Aucune expérience préalable n'est requise. AI Agents sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.
Combien de temps prend la leçon « Application des politiques aux actions des agents » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon AI Agents ?
Oui. Chaque leçon AI Agents inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Journalisation immuable des actions des agents
- Application des politiques aux actions des agents
- Conformité réglementaire : GDPR et SOC2
- Portes d’approbation avec intervention humaine