# ContextOS MCP tool-supply-chain policy starter
# Illustrative deployment policy, not a normative ContextOS runtime schema.
schema_version: contextos.ai/examples/mcp-admission-policy/v1
kind: McpAdmissionPolicy

metadata:
  name: repository-support-mcp
  owner: platform-security
  incident_contact: security-on-call
  review_interval_days: 30

spec:
  default_decision: deny

  server:
    endpoint: https://mcp.example.internal/v1
    transport: streamable_http
    protocol_versions:
      - "2025-11-25"
    require_tls: true
    require_server_identity: true
    allowed_redirect_origins: []

  admission:
    require_named_owner: true
    require_security_review: true
    accept_live_schema_drift: false
    accept_live_tool_additions: false
    treat_descriptions_as: untrusted_data
    require_pins:
      - server_identity
      - protocol_version
      - tool_name
      - input_schema_hash
      - output_schema_hash
      - description_hash

  principals:
    require_agent_identity: true
    require_delegated_user_for:
      - support.create_ticket
    validate_tenant_equality: true
    token_passthrough: deny
    credential_policy:
      lifetime_seconds_max: 300
      require_resource_audience: true
      expose_credentials_to_model: false
      log_credentials: false

  capabilities:
    - name: repository.search
      approval_mode: read_only
      allowed_paths:
        - /workspace/repository/**
      denied_paths:
        - /workspace/repository/.env*
        - /workspace/repository/**/.credentials/**
        - /workspace/repository/**/.ssh/**
      network_access: false

    - name: workspace.read_file
      approval_mode: read_only
      require_intent_bound_path: true
      allowed_paths:
        - /workspace/repository/**
      denied_paths:
        - /workspace/repository/.env*
        - /workspace/repository/**/.credentials/**
        - /workspace/repository/**/.ssh/**
      network_access: false

    - name: support.create_ticket
      approval_mode: delegated
      allowed_destinations:
        - https://support.example.internal/api/tickets
      allowed_data_scopes:
        - PUBLIC
        - INTERNAL
      denied_fields:
        - authorization
        - cookie
        - credential
        - private_key
        - secret
        - token
      require_payload_preview: true
      require_effect_specific_approval: true
      require_idempotency_key: true

  forbidden_compositions:
    - name: untrusted-content-to-sensitive-read
      when:
        sources:
          - mcp_description
          - mcp_resource
          - mcp_tool_result
        sinks:
          - workspace.read_file
      unless:
        controls:
          - intent_bound_path
          - denied_path_enforced

    - name: sensitive-read-to-network
      when:
        sources:
          - workspace.read_file
        sinks:
          - support.create_ticket
      unless:
        controls:
          - data_classification_passed
          - destination_bound
          - payload_previewed
          - effect_specific_approval

  runtime:
    require_fresh_policy_decision_per_call: true
    validate_arguments_against_schema: true
    bind_arguments_to_user_intent: true
    deny_unapproved_destinations: true
    deny_cross_tenant_access: true
    timeout_seconds_max: 30
    retries_max: 1
    require_idempotency_for_writes: true
    sandbox:
      inherit_host_environment: false
      inherit_host_credentials: false
      filesystem_default: deny
      network_default: deny

  outputs:
    require_source_provenance: true
    separate_structured_data_from_text: true
    treat_natural_language_as: untrusted_data
    allow_output_to_expand_tool_set: false
    allow_automatic_memory_promotion: false
    redact_before_model_context:
      - credentials
      - secrets
      - restricted_data

  evidence:
    record_accepted_calls: true
    record_denied_calls: true
    record_policy_decision_id: true
    record_manifest_hash: true
    record_schema_hashes: true
    record_argument_hash: true
    record_result_hash: true
    record_mutation_receipts: true
    preserve_replay_inputs: true

  revocation:
    kill_switch_required: true
    block_new_discovery: true
    block_context_compilation: true
    block_in_flight_execution: true
    revoke_active_credentials: true
    quarantine_long_running_tasks: true
    require_new_version_for_readmission: true

  release_tests:
    required:
      - poisoned_tool_description
      - poisoned_tool_result
      - cross_tool_exfiltration
      - hidden_parameter_tampering
      - wrong_token_audience
      - token_passthrough
      - expired_agent_identity
      - cross_tenant_access
      - schema_drift
      - live_tool_addition
      - unapproved_destination
      - duplicate_write_after_timeout
      - kill_switch_during_execution
