---
name: gsc_auth
kind: function
lang: py
domain: infra
version: "1.0.0"
purity: impure
signature: "def gsc_auth(credentials_path: str = \"\", subject: str = \"\") -> object"
description: "Autentica contra la Google Search Console API v1 (searchconsole/webmasters) con una cuenta de servicio JSON. Lee el JSON de credentials_path o, si esta vacio, de la env var GSC_SA_JSON; lanza ValueError claro si falta. Usa service_account.Credentials.from_service_account_file con scope https://www.googleapis.com/auth/webmasters.readonly (solo lectura). subject opcional aplica with_subject(subject) para domain-wide delegation (normalmente vacio en GSC). Construye y retorna el objeto service de googleapiclient.discovery.build('searchconsole','v1', cache_discovery=False) listo para consumir por pull_gsc_search_analytics. Requiere google-api-python-client y google-auth."
tags: [seo, gsc, infra, google, search-console, auth, service-account]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: [os, google.oauth2.service_account, googleapiclient.discovery]
params:
  - name: credentials_path
    desc: "ruta al JSON de la service account de GCP. Si esta vacio, se lee de la env var GSC_SA_JSON. Si tampoco existe, se lanza ValueError. El JSON es un secreto: resolver desde pass o una ruta fuera del repo, nunca commitear."
  - name: subject
    desc: "opcional. Email para domain-wide delegation (impersonation) via with_subject. Normalmente vacio en Search Console, donde la SA se anade directamente como usuario en GSC sin requerir delegation."
output: "object. El service de googleapiclient (googleapiclient.discovery.Resource) para la API 'searchconsole' v1, autenticado con scope webmasters.readonly y cache_discovery=False. Se pasa a funciones consumidoras como pull_gsc_search_analytics."
tested: true
tests:
  - "test_build_se_llama_con_searchconsole_v1_y_cache_off"
  - "test_credentials_se_cargan_con_scope_readonly"
  - "test_fallback_a_env_var_gsc_sa_json"
  - "test_subject_aplica_with_subject"
  - "test_error_cuando_falta_credential"
test_file_path: "python/functions/infra/gsc_auth_test.py"
file_path: "python/functions/infra/gsc_auth.py"
---

## Ejemplo

```python
import sys
sys.path.insert(0, "python/functions")
from infra import gsc_auth

# Opcion A: ruta explicita al JSON de la service account
service = gsc_auth(credentials_path="/home/enmanuel/secrets/gsc-sa.json")

# Opcion B: leer la ruta de la env var GSC_SA_JSON
#   export GSC_SA_JSON=/home/enmanuel/secrets/gsc-sa.json
service = gsc_auth()

# Verificar la autenticacion listando los sitios verificados:
sites = service.sites().list().execute()
print([s["siteUrl"] for s in sites.get("siteEntry", [])])
```

## Cuando usarla

Antes de `pull_gsc_search_analytics` (o cualquier llamada a la Search Console
API): la usas para obtener el objeto `service` autenticado una sola vez y
reutilizarlo en las consultas posteriores (Search Analytics, sitemaps, sites).
Es el punto de entrada del capability group `seo`.

## Gotchas

- **Impura**: lee un JSON del disco y construye un cliente HTTP de Google. No
  es determinista ni componible en el nucleo puro.
- **Dar de alta la SA en Search Console**: el email de la service account debe
  anadirse manualmente como usuario en Search Console > Settings > Users and
  permissions (rol Restricted/Full). Sin esto la auth funciona pero las
  consultas devuelven 403 / sitios vacios.
- **Habilitar la API**: la "Search Console API" debe estar habilitada en el
  proyecto GCP de la service account (consola de APIs & Services). Si no, el
  primer `.execute()` falla con un error de API deshabilitada.
- **El JSON de la SA es un secreto**: no commitear nunca. Guardarlo en `pass`
  o en una ruta fuera del repo y pasar la ruta por `credentials_path` o la env
  var `GSC_SA_JSON`.
- **`subject` casi siempre vacio**: domain-wide delegation solo aplica si
  impersonas a un usuario de un dominio Workspace; en GSC lo normal es anadir
  la SA directamente como usuario y dejar `subject=""`.
- **Dependencias**: requiere `google-api-python-client` y `google-auth` en el
  venv. Ya estan en `python/pyproject.toml`.

## Capability growth log

(sin cambios — v1.0.0 inicial)
