Skip to content

brunoinnacio/SailPoint-ISC-Python-Integrations

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SailPoint ISC Lab — Simulador Local de Identity Security Cloud

Um laboratório prático que reconstrói, do zero e em Python, o fluxo completo de governança de identidade do SailPoint Identity Security Cloud (ISC) — da fonte autoritativa (RH) até o provisionamento no Active Directory — sem depender de um tenant corporativo.

Python 3.13 FastAPI Uvicorn PowerShell SailPoint ISC Status License: MIT


Sobre o projeto

O SailPoint ISC é uma plataforma de IAM (Identity & Access Management) que orquestra o ciclo de vida das identidades de uma empresa: ela lê quem são as pessoas em uma fonte autoritativa (ex.: RH/Protheus), monta a Identity de cada uma e, quando um acesso é aprovado, provisiona esse acesso nos sistemas-alvo (ex.: Active Directory).

Este repositório recria esse fluxo inteiro localmente, peça por peça, para estudo e demonstração de habilidades de integração. Cada componente do SailPoint tem aqui um equivalente construído à mão em Python/PowerShell — o que permite entender o que acontece por baixo dos panos de uma plataforma de IAM.

Construído passo a passo como treinamento prático de IAM + APIs REST + Webhooks + automação com PowerShell.


Arquitetura

flowchart TD
    RH["RH / Authoritative Source<br/><code>passo1_authoritative_source_api.py</code>"]
    AGG["Aggregation — motor do ISC<br/><code>passo2_aggregation.py</code>"]
    ISC["Event Trigger do ISC<br/><code>passo3_event_sender.py</code>"]
    WH["Webhook Listener<br/><code>passo3_webhook_listener.py</code>"]
    REQ["Access Request + Approval<br/><code>passo5_access_request_api.py</code>"]
    SOD{"Política de SoD?<br/><code>passo6_sod_policy.py</code>"}
    PONTE["Ponte / IQService<br/><code>passo4_iqservice_bridge.py</code>"]
    PS["Script no Target System<br/><code>passo4_provision_ad.ps1</code>"]
    AD[("Active Directory<br/>ad_provisionamento.log")]
    BLOCK["Bloqueada / Rejeitada<br/>(nada provisionado)"]

    RH -->|"GET (lê a verdade)"| AGG
    ISC -->|"POST · Event Trigger"| WH
    WH --> PONTE
    REQ -->|"gestor aprova"| SOD
    SOD -->|"sem conflito"| PONTE
    SOD -->|"conflito"| BLOCK
    PONTE -->|"subprocess"| PS
    PS -->|"provisiona / desativa"| AD
Loading

O laboratório cobre as duas metades do IGA: Administration (ler a fonte e provisionar — caminhos RH → Aggregation e Webhook → Ponte) e Governance (o acesso só é provisionado após aprovação e desde que não viole a política de SoD — caminho Access Request → SoD).


O que este projeto demonstra

  • Construção de APIs REST com FastAPI (rotas GET e POST, validação com Pydantic, status HTTP, documentação automática via Swagger).
  • Consumo de APIs com requests, incluindo tratamento de erros de conexão e timeouts.
  • Arquitetura orientada a eventos (webhooks): inverter a lógica de "perguntar" para "ser notificado".
  • Integração entre linguagens: ponte Python → PowerShell via subprocess, capturando saída e contornando ExecutionPolicy.
  • Modelagem de dados com objetos aninhados (uma Identity dentro de um evento).
  • Workflow de governança (IGA): solicitação de acesso → aprovação → provisionamento, com trilha de auditoria (quem pediu, quem aprovou, quando e por quê).
  • Enforcement de políticas: Segregation of Duties (SoD) bloqueando combinações de acessos conflitantes, mesmo sobre a decisão do aprovador.
  • Autenticação de API como em produção: fluxo OAuth2 (client_credentials) com Bearer token, no mesmo formato do tenant real do ISC.
  • Boas práticas: ambiente virtual isolado, requirements.txt como contrato de versões, segredos e artefatos fora do versionamento.
  • Tradução de conceitos de IAM/IGA (Authoritative Source, Aggregation, Event Trigger, IQService, Target System, Access Request, Approval, SoD) para código funcional.

Mapa de conceitos — SailPoint ISC × este laboratório

Conceito SailPoint (ISC) O que é na vida real Como simulamos aqui
Authoritative Source Fonte da verdade das pessoas (RH/Protheus) API FastAPI que devolve dados de funcionários (PASSO 1)
Identity A identidade única de uma pessoa dentro do ISC O objeto JSON que o ISC monta a partir do RH
Aggregation ISC "puxa" os dados da fonte para criar/atualizar Identities Script Python que faz GET na API do RH (PASSO 2)
Event Trigger Evento do ISC que dispara uma ação externa (HTTP POST) JSON que o "ISC" envia ao nosso Webhook (PASSO 3)
Webhook Listener Endpoint que recebe o Event Trigger Rota POST na nossa API FastAPI (PASSO 3)
IQService Conector que executa ações no Windows/AD Ponte Python → script PowerShell (PASSO 4)
Target System Sistema onde o acesso é provisionado (ex.: AD) Active Directory simulado via PowerShell (PASSO 4)
Access Profile / Entitlement Pacote de acessos concedidos a uma Identity O grupo/papel que o PowerShell aplica no AD
Access Request / Approval Pedido de acesso aprovado por um gestor antes de conceder API de solicitações com aprovação e auditoria (PASSO 5)
Segregation of Duties (SoD) Política que impede combinações de acessos com risco/fraude Motor que bloqueia pares conflitantes na aprovação (PASSO 6)
API Authentication OAuth2 (client_credentials) + Bearer token para chamar o ISC Mock do ISC com /oauth/token e endpoints /v3 (PASSO 7)

Stack

  • Python 3.13 — linguagem principal
  • FastAPI 0.115 — framework das APIs REST (RH e Webhook)
  • Uvicorn 0.34 — servidor ASGI que coloca as APIs no ar
  • Requests 2.32 — cliente HTTP (simula o motor do ISC consumindo/disparando)
  • python-multipart — suporte a formulários (fluxo OAuth2 do PASSO 7)
  • PowerShell — executa a ação no Target System (Active Directory)

Estrutura do projeto

SailPoint_ISC_Lab/
├── passo1_authoritative_source_api.py  # Authoritative Source: API REST que devolve as Identities (GET)
├── passo2_aggregation.py               # Aggregation: motor do ISC consumindo a RH API
├── passo3_webhook_listener.py          # Webhook Listener: recebe o Event Trigger (POST) e aciona a ponte
├── passo3_event_sender.py              # Simula o ISC disparando o Event Trigger
├── passo4_iqservice_bridge.py          # IQService: ponte Python -> PowerShell (subprocess)
├── passo4_provision_ad.ps1             # Target System (AD) simulado: registra a ação
├── passo5_access_request_api.py        # IGA: solicitação de acesso + aprovação + auditoria
├── passo5_access_request_demo.py       # Simula o fluxo pedido -> aprovação/rejeição -> auditoria
├── passo6_sod_policy.py                # IGA: política de Segregation of Duties (SoD)
├── passo6_sod_demo.py                  # Simula a SoD bloqueando uma combinação tóxica
├── passo7_isc_mock_api.py              # Mock do ISC real: OAuth2 + endpoints /v3 protegidos
├── passo7_isc_client.py                # Cliente que autentica (Bearer) e consome, como em produção
├── docs/
│   └── POC_offboarding.md              # Roteiro de POC para propor automação na empresa
├── requirements.txt                    # Contrato de versões das dependências
├── .gitignore                          # Ignora .venv, __pycache__, *.log, segredos
├── LICENSE                     # Licença MIT
└── README.md

Como executar

1. Preparação do ambiente (uma vez por máquina)

# Criar o ambiente virtual isolado
py -m venv .venv

# Liberar scripts SÓ para esta sessão do PowerShell (não altera a máquina)
Set-ExecutionPolicy -Scope Process -ExecutionPolicy RemoteSigned

# Ativar o ambiente -> o prompt passa a exibir "(.venv)"
.\.venv\Scripts\Activate.ps1

# Instalar as dependências
pip install -r requirements.txt

Dica: Set-ExecutionPolicy -Scope Process vale apenas para a janela atual — todo terminal novo precisa rodá-lo de novo antes do Activate.ps1. Para um comando pontual sem ativar nada, chame o Python interno: .\.venv\Scripts\python.exe <arquivo>.py.

2. Demonstração rápida do fluxo completo

# Terminal 1 — Webhook Listener (já aciona a ponte para o PowerShell)
uvicorn passo3_webhook_listener:app --reload --port 8001

# Terminal 2 — simula o ISC aprovando um acesso e disparando o evento
python passo3_event_sender.py

Resultado: o Terminal 1 mostra o evento recebido e a resposta do PowerShell; o arquivo ad_provisionamento.log registra o provisionamento — a "prova física" da ação no AD.


Os passos (com testes)

PASSOS 1–4 = Administration (ler a fonte e provisionar). PASSOS 5–6 = Governance (aprovação e política de SoD). PASSO 7 = integração como em produção (OAuth2).

Índice de ordem de aprendizado — o prefixo passoN_ no nome de cada arquivo já indica a sequência; a tabela abaixo agrupa os arquivos de cada passo e resume o papel de cada um:

Ordem Arquivo(s) principal(is) Papel
1 passo1_authoritative_source_api.py Fonte da verdade (RH) — API REST
2 passo2_aggregation.py Motor do ISC consumindo a fonte
3 passo3_webhook_listener.py · passo3_event_sender.py Event Trigger / Webhook
4 passo4_iqservice_bridge.py · passo4_provision_ad.ps1 Ponte Python → PowerShell (AD)
5 passo5_access_request_api.py · passo5_access_request_demo.py IGA: solicitação + aprovação + auditoria
6 passo6_sod_policy.py · passo6_sod_demo.py IGA: Segregation of Duties
7 passo7_isc_mock_api.py · passo7_isc_client.py OAuth2/Bearer como em produção
PASSO 1 — Authoritative Source (RH API)

Objetivo: subir a API REST que é a fonte da verdade das pessoas (o "Protheus") e devolver as Identities em JSON via GET.

uvicorn passo1_authoritative_source_api:app --reload
URL O que valida Esperado
http://127.0.0.1:8000/funcionarios Aggregation completa (lista todos) JSON com os 3 funcionários
http://127.0.0.1:8000/funcionarios/1001 Buscar uma Identity JSON só da Ana Souza
http://127.0.0.1:8000/funcionarios/9999 Tratamento de erro Erro 404 com mensagem amigável
http://127.0.0.1:8000/docs Documentação automática Swagger interativo
PASSO 2 — Aggregation (motor do ISC)

Objetivo: fazer um GET na RH API e decidir, pelo campo status, criar/atualizar ou desativar cada Identity. Demonstra os dois lados de uma integração rodando ao mesmo tempo.

# Terminal 1
uvicorn passo1_authoritative_source_api:app --reload
# Terminal 2
python passo2_aggregation.py

Esperado: Ana e Bruno como CRIAR/ATUALIZAR Identity (ativos) e Carla como DESATIVAR Identity (inativa).

Teste de robustez: pare a API e rode o PASSO 2 — deve aparecer a mensagem amigável de falha de conexão em vez de um stack trace.

PASSO 3 — Event Trigger / Webhook Listener

Objetivo: receber um POST (o Event Trigger do ISC) em vez de responder GET. Inverte a lógica: a API fica esperando ser chamada e age quando o evento chega.

# Terminal 1
uvicorn passo3_webhook_listener:app --reload --port 8001
# Terminal 2
python passo3_event_sender.py

Esperado: Terminal 2 recebe Status HTTP 200 + ACK; Terminal 1 mostra o bloco EVENTO RECEBIDO DO ISC. Alternativa: testar pelo Swagger em http://127.0.0.1:8001/docs.

PASSO 4 — Ponte Python → PowerShell (IQService)

Objetivo: transformar a ordem recebida no webhook em ação real. A ponte executa o passo4_provision_ad.ps1, que simula o AD registrando a ação em ad_provisionamento.log.

# Testar a ponte isoladamente
.\.venv\Scripts\python.exe passo4_iqservice_bridge.py

Esperado: returncode: 0, mensagem PROVISIONADO no AD: ... e o log atualizado. No fluxo completo (PASSO 3), o webhook já chama a ponte automaticamente.

A ponte chama o PowerShell com -ExecutionPolicy Bypass, então o script roda sem depender da política da sessão. Em produção, basta trocar a simulação pelos cmdlets reais (New-ADUser, Add-ADGroupMember) já comentados no .ps1.

PASSO 5 — IGA: Access Request + Approval workflow

Objetivo: adicionar o portão de governança. O acesso só é provisionado após aprovação, e tudo fica registrado (trilha de auditoria: quem pediu, quem decidiu, quando e por quê). Reaproveita a ponte do PASSO 4 para provisionar quando aprovado.

# Terminal 1
uvicorn passo5_access_request_api:app --reload --port 8002
# Terminal 2
python passo5_access_request_demo.py

Endpoints: POST /solicitacoes (pedir), GET /solicitacoes (auditoria), POST /solicitacoes/{id}/aprovar (aprova e provisiona), POST /solicitacoes/{id}/rejeitar.

Esperado: a solicitação aprovada vira provisionamento no AD (returncode 0); a rejeitada não toca no AD. Aprovar/rejeitar uma solicitação já decidida retorna 409 Conflict.

PASSO 6 — IGA: Segregation of Duties (SoD)

Objetivo: impedir que uma pessoa acumule acessos conflitantes (ex.: criar e aprovar pagamentos). A política é verificada na aprovação do PASSO 5 e prevalece sobre a decisão do gestor (controle preventivo). As políticas ficam em passo6_sod_policy.py.

# Terminal 1
uvicorn passo5_access_request_api:app --reload --port 8002
# Terminal 2
python passo6_sod_demo.py

Esperado: o primeiro acesso (AD-Pagamentos-Criar) é concedido; o segundo (AD-Pagamentos-Aprovar) é bloqueado com 409 pela política SoD-Pagamentos, e nada é provisionado. A solicitação fica com status bloqueada_sod na auditoria.

PASSO 7 — Conectando como em produção (OAuth2 + Bearer)

Objetivo: falar com o ISC do jeito real — autenticando via OAuth2 (client_credentials) e usando Bearer token nas chamadas /v3. O mock imita o tenant; o cliente usa o mesmo código que apontaria para um ISC de verdade (basta trocar BASE_URL e as credenciais).

# Terminal 1
uvicorn passo7_isc_mock_api:app --reload --port 8003
# Terminal 2
python passo7_isc_client.py

Esperado: autentica (recebe token), lista identities, cria um access request PENDING e, ao chamar sem token, recebe 401/403 (segurança). O SDK oficial sailpoint (Python) faz esse mesmo fluxo por baixo dos panos.


Exercícios para praticar

Sugestões para fixar os conceitos. Antes de rodar cada um, tente prever o resultado — é o que faz o aprendizado grudar. (As APIs precisam estar no ar conforme cada passo.)

Nível 1 — Webhook e provisionamento (PASSOS 3–4)

  1. Trocar a pessoa: no passo3_event_sender.py, mude o evento para o Bruno Lima (id 1002, grupo AD-Grupo-TI) e rode. Confira a nova linha no ad_provisionamento.log.
  2. Desprovisionar: mude "acao" para "desprovisionar" e rode. O log deve registrar DESPROVISIONADO.
  3. Quebrar de propósito: remova o campo access_profile do evento e rode. O Status HTTP deve ser 422 (Pydantic recusando), e nada deve ser escrito no log.

Nível 2 — Access Request + Approval (PASSO 5)

  1. Rejeitar um pedido: crie uma solicitação (POST /solicitacoes) e use POST /solicitacoes/{id}/rejeitar. Confirme que o status vira rejeitada e que o AD não foi tocado.
  2. Decidir duas vezes: aprove uma solicitação e tente aprová-la de novo. Você deve receber 409 Conflict. Por que isso é importante em governança?
  3. Auditoria: após várias decisões, chame GET /solicitacoes e identifique, para cada uma, quem decidiu e quando.

Nível 3 — Segregation of Duties (PASSO 6)

  1. Inverter a ordem: no passo6_sod_demo.py, peça primeiro AD-Pagamentos-Aprovar e depois AD-Pagamentos-Criar. A SoD ainda bloqueia? (Deve bloquear — a política é simétrica.)
  2. Criar sua própria política: em passo6_sod_policy.py, adicione uma nova regra ao SOD_POLICIES (ex.: AD-Grupo-Financeiro x AD-Grupo-Auditoria) e demonstre o bloqueio.
  3. Acesso não-conflitante: solicite e aprove um acesso que não participa de nenhuma SoD (ex.: AD-Grupo-TI). Confirme que ele é concedido normalmente.

Quando terminar, me mostre os resultados (ou os erros) — posso comentar o "gabarito" de cada um.


Solução de problemas (troubleshooting)

Sintoma Causa provável Correção
"a execução de scripts foi desabilitada neste sistema" Terminal novo sem liberar ExecutionPolicy Rode Set-ExecutionPolicy -Scope Process -ExecutionPolicy RemoteSigned
"não consegui conectar na RH API" (PASSO 2) API do PASSO 1 fora do ar Suba uvicorn passo1_authoritative_source_api:app --reload
"não consegui conectar no Webhook Listener" (PASSO 3) Webhook do PASSO 3 fora do ar Suba uvicorn passo3_webhook_listener:app --reload --port 8001
"passo3_event_sender.py não é reconhecido como cmdlet" Faltou chamar o Python (rodou o .py direto) Use python passo3_event_sender.py (não use .\arquivo.py)
uvicorn/python "não reconhecido" .venv não ativado Ative o .venv ou use .\.venv\Scripts\python.exe
Webhook não inicia: "address already in use" Porta 8001/8002 já ocupada Pare o processo antigo ou use outra porta (--port 8003)
Aprovação retorna 409 Conflict Solicitação já decidida ou violação de SoD Comportamento esperado — confira o corpo da resposta (motivo)
Chamada /v3 retorna 401/403 (PASSO 7) Token ausente, inválido ou expirado Autentique em /oauth/token e envie Authorization: Bearer <token>

Roadmap

Administration (concluído):

  • PASSO 1 — Authoritative Source (RH API)
  • PASSO 2 — Aggregation (motor do ISC)
  • PASSO 3 — Event Trigger / Webhook Listener
  • PASSO 4 — Ponte com PowerShell (IQService → Target System)

Governance / IGA (concluído):

  • PASSO 5 — Access Request + Approval workflow (com trilha de auditoria)
  • PASSO 6 — Segregation of Duties (SoD)

Integração como em produção (concluído):

  • PASSO 7 — Autenticação OAuth2 (Bearer) e chamadas no estilo /v3 do ISC

Próximas evoluções possíveis:

  • Access Certification — revisão periódica em que o gestor confirma/revoga acessos
  • RBAC / Roles — agrupar entitlements em papéis por cargo
  • Integrar o SDK oficial sailpoint (Python) contra um tenant/sandbox real
  • Provisionar em um Active Directory real (descomentar os cmdlets do .ps1)
  • Testes automatizados (pytest) e CI

Autor

Bruno Inácio — Especialista em Automação de Testes (Sênior), com mais de 7 anos em automação e 15 anos em QA, atuando em sistemas bancários, logísticos e de streaming. Forte base em testes de API, CI/CD, Python, Robot Framework, Selenium e cloud (AWS/Azure), expandindo a atuação para integração de sistemas e IAM (Identity & Access Management).

Este laboratório nasceu da curiosidade de entender, na prática, como plataformas de IAM orquestram identidades e acessos — aplicando minha experiência em testes de API e automação para construir uma integração ponta a ponta, e não apenas validá-la.

📍 Rio de Janeiro, Brasil  ·  📧 [email protected]

GitHub LinkedIn


Licença

Distribuído sob a Licença MIT — você pode estudar, usar e adaptar o código, desde que mantenha o aviso de copyright. Veja o arquivo LICENSE para os termos completos.

© 2026 Bruno Inácio · Licenciado sob a Licença MIT

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors