#InterSystems API Manager (IAM)

0 Abonnés · 15 Publications

InterSystems API Manager (IAM) vous permet de surveiller et de contrôler le trafic vers et depuis vos API basées sur le web. Si vous créez des couches d'applications orientées services, il est fort probable que le nombre d'API que vous utilisez augmente rapidement. Plus votre environnement est distribué, plus il est essentiel de gérer et de surveiller correctement votre trafic d'API. Le gestionnaire d'API vous permet d'acheminer facilement tout votre trafic via une passerelle centralisée et de transmettre les demandes d'API aux nœuds cibles appropriés.

Ressources supplémentaires : 
Documentation
Présentation d'InterSystems API Manager [Article] 
Qu'est-ce que InterSystems API Manager [Video] 
Introduction à InterSystems API Manager [Video] 
InterSystems API Manager: Démonstration de l'usine de bonbons [Video] 

Article Sylvain Guilbaud · Juil 18, 2025 11m read

🛠️ Gestion des configurations d'InterSystems API Manager (IAM = Kong Gateway) en CI/CD

🔍 Contexte : configurations d'InterSystems IAM

Dans le cadre de l'intégration d'InterSystems IAM dans un environnement sécurisé et contrôlé, InterSystems IAM repose sur Kong Gateway pour gérer les API exposées. Kong agit comme une API Gateway moderne, capable de gérer l’authentification, la sécurité, la gestion du trafic, les plugins, et bien plus encore.

0
0 24
Article Guillaume Rongier · Juin 23, 2025 27m read

Introduction

Dans le contexte actuel où les menaces évoluent rapidement, les organisations qui déploient des applications critiques doivent mettre en œuvre des architectures de sécurité robustes qui protègent les données sensibles tout en maintenant une haute disponibilité et des performances élevées. Cela est particulièrement crucial pour les entreprises qui utilisent des systèmes de gestion de bases de données avancés tels qu'InterSystems IRIS, qui alimentent souvent des applications traitant des données hautement sensibles dans les domaines de la santé, de la finance ou des données personnelles.

Cet article décrivent en détail une architecture de sécurité complète à plusieurs niveaux pour le déploiement de clusters InterSystems IRIS sur AWS à l'aide de Kubernetes (EKS) et InterSystems IAM. En appliquant les principes de défense en profondeur, cette architecture fournit une protection à tous les niveaux, du périmètre du réseau au niveau de l'application et du stockage des données.

Pourquoi une approche à plusieurs niveaux est-elle importante

Les stratégies de sécurité à un seul niveau sont de plus en plus inadéquates face à des vecteurs d'attaque sophistiqués. Lorsqu'un contrôle de sécurité échoue, des niveaux supplémentaires doivent être mis en place pour éviter une compromission totale. Notre architecture implémente des contrôles de sécurité à cinq niveaux critiques:

  1. Sécurité périmétrique: Utilisation d'AWS WAF et CloudFront pour filtrer le trafic malveillant avant qu'il n'atteigne vos services
  2. Sécurité réseau: Exploitation des stratégies réseau AWS VPC, des groupes de sécurité et de Kubernetes
  3. Sécurité des API: Implémentation d'InterSystems IAM avec des plug-ins de sécurité avancés
  4. Sécurité des applications: Renforcement de la passerelle Web grâce à des restrictions URI rigoureuses
  5. Sécurité des bases de données: Configuration du cluster IRIS avec authentification et chiffrement robustes

À la fin de cet article, vous comprendrez comment mettre en œuvre chaque couche de sécurité et comment elles fonctionnent conjointement pour créer une stratégie de défense en profondeur qui protège vos déploiements IRIS contre un large éventail de menaces tout en préservant les performances et l'évolutivité.
 


Aperçu de l'architecture

Notre architecture de sécurité repose sur le principe de la défense en profondeur, chaque niveau fournissant une protection complémentaire. Voici un aperçu général de la solution complète:


Structure de déploiement du cluster IRIS

Notre cluster IRIS est déployé à l'aide de l'Opérateur Kubernetes d'InterSystems (IKO) selon une topologie soigneusement conçue:

  1. Niveau de données: Deux instances IRIS dans une configuration en miroir pour une haute disponibilité et une redondance des données
  2. Niveau d'application: Deux serveurs d'applications IRIS qui accèdent aux données via ECP (Enterprise Cache Protocol)
  3. Passerelle API: InterSystems IAM (basé sur Kong) pour la gestion et la sécurité des API
  4. Passerelle Web: Trois instances de passerelle Web (CSP+Nginx) pour traiter les requêtes Web
  5. Arbitre: Une instance d'arbitre pour le niveau de données en miroir

Cette architecture sépare les problèmes et fournit plusieurs niveaux de redondance:

  • Le niveau de données gère les opérations de base de données avec mise en miroir synchrone
  • Le niveau d'application se concentre sur le traitement de la logique métier
  • Le niveau IAM gère la sécurité des API
  • Le niveau de passerelle Web traite les requêtes HTTP/HTTPS

Chaque composant joue un rôle spécifique dans la pile de sécurité:

  1. AWS WAF (pare-feu d'application Web): filtre le trafic malveillant à l'aide d'ensembles de règles qui protègent contre les exploits Web courants, les injections SQL et les scripts intersites (XSS). Il met également en œuvre une liste blanche d'URI pour restreindre l'accès aux seuls chemins d'application légitimes.
  2. AWS CloudFront: Agit comme un réseau de diffusion de contenu (CDN) qui met en cache le contenu statique, réduisant ainsi la surface d'attaque en traitant les demandes à la périphérie. Il fournit également un niveau supplémentaire de protection contre les attaques DDoS.
  3. AWS ALB (Équilibreur de charge d'application): Configuré comme un contrôleur d'entrée Kubernetes, il effectue la terminaison TLS et achemine le trafic vers les services backend appropriés en fonction des chemins d'URL.
  4. InterSystems IAM: Basée sur Kong, cette passerelle API applique l'authentification, l'autorisation, la limitation du débit et la validation des requêtes avant que le trafic n'atteigne l'application.
  5. Passerelle Web: La passerelle Web InterSystems, avec sa configuration renforcée, restreint l'accès à des chemins URI spécifiques et fournit une validation supplémentaire.
  6. Cluster IRIS: La base de données IRIS déployée dans un cluster Kubernetes avec une configuration sécurisée, un chiffrement TLS et des contrôles d'accès basés sur les rôles.

Cette approche à plusieurs niveaux garantit que même si un contrôle de sécurité est contourné, les autres restent en place pour protéger vos applications et vos données.


Niveau 1: Sécurité périmétrique avec AWS WAF et CloudFront

La première ligne de défense de notre architecture se situe au périmètre du réseau, où nous mettons en œuvre AWS WAF et CloudFront pour filtrer le trafic malveillant avant qu'il n'atteigne nos services.

1.1 Mise en œuvre d'AWS WAF

Le pare-feu d'application Web AWS est configuré avec des ensembles de règles personnalisées afin de protéger contre les exploits Web courants et de restreindre l'accès aux chemins URI autorisés uniquement. Voici comment nous l'avons configuré:

# WAF Configuration in Ingress alb.ingress.kubernetes.io/wafv2-acl-arn: arn:aws:wafv2:region-1:ACCOUNT_ID:regional/webacl/app_uri_whitelisting/abcdef123456 

Nos règles WAF sont les suivantes:

  • Liste blanche des chemins URI: Autorisation du trafic uniquement vers les chemins d'application spécifiés, tels que /app/, /csp/broker/, /api/, and /csp/appdata
  • Protection contre les injections SQL: Blocage des requêtes contenant des modèles d'injection SQL
  • Protection XSS: Filtrage des requêtes contenant des charges utiles de type cross-site scripting
  • Regles basées sur les taux: Blocage automatique des adresses IP qui dépassent les seuils de requêtes
  • Règles de limitation géographique: Limitation de l'accès à certaines zones géographiques lorsque cela est nécessaire

En appliquant ces règles à la périphérie, nous empêchons une grande partie du trafic malveillant d'atteindre notre infrastructure d'applications.
 

1.2 Intégration CloudFront

AWS CloudFront fonctionne avec WAF pour fournir des avantages supplémentaires en matière de sécurité:

  • Mise en cache intelligente: le contenu statique est mis en cache à des emplacements périphériques, ce qui réduit la charge sur les services backend et minimise la surface d'attaque
  • Protection contre les attaques DDoS: L'infrastructure distribuée à l'échelle globale de CloudFront aide à absorber les attaques DDoS
  • Application du protocole TLS: Toutes les connexions sont sécurisées à l'aide du protocole TLS 1.2+ et de suites de chiffrement modernes
  • Identité d'accès à l'origine: Garantie que les compartiments S3 hébergeant du contenu statique sont uniquement accessibles via CloudFront

CloudFront est configuré pour transférer des en-têtes spécifiques vers les services backend, garantissant ainsi la préservation des contextes de sécurité tout au long du flux de requêtes:

  • X-Forwarded-For
  • X-Real-IP

Cette configuration permet aux services en aval d'identifier l'adresse IP client d'origine à des fins de limitation du débit et de journalisation, même lorsque les requêtes transitent par plusieurs niveaux.


Niveau 2: Sécurité réseau avec AWS VPC et groupes de sécurité

Le deuxième niveau de notre architecture de sécurité se concentre sur les contrôles au niveau du réseau mis en œuvre via AWS VPC, les groupes de sécurité et les stratégies réseau Kubernetes.

2.1 Conception VPC pour l'isolation

Notre déploiement IRIS s'exécute dans un VPC personnalisé avec les caractéristiques suivantes:

  • Sous-réseaux privés: Tous les pods IRIS et IAM s'exécutent dans des sous-réseaux privés sans accès direct à l'Internet
  • Passerelles NAT: Outbound internet access
  • Plusieurs zones de disponibilité: Les ressources sont réparties sur trois zones de disponibilité pour une haute disponibilité

Cette conception garantit qu'aucun service backend n'est directement exposé à l'Internet, tout le trafic passant par des points d'entrée contrôlés.

2.2 Configuration des groupes de sécurité

Les groupes de sécurité agissent comme des pare-feu virtuels qui contrôlent le trafic entrant et sortant. Notre implémentation comprend plusieurs groupes de sécurité avec des règles rigoureusement définies:

# Groupes de sécurité référencés dans Ingress alb.ingress.kubernetes.io/security-groups: sg-000000000, sg-0100000000, sg-012000000, sg-0130000000  Ces groupes de sécurité mettent en œuvre:
  • Règles d'entrée: N'autorisent le trafic que sur les ports requis (443 pour HTTPS)
  • Restrictions IP source: Limitent l'accès à des blocs CIDR spécifiques pour les interfaces administratives
  • Règles de sortie: Restriction des connexions sortantes aux destinations nécessaires

Ce niveau de contrôle très précis garantit que, même si un conteneur est compromis, sa capacité à communiquer avec d'autres ressources est limitée par les règles du groupe de sécurité.

2.3 Stratégies réseau Kubernetes

Au sein du cluster EKS, nous mettons en œuvre des stratégies réseau Kubernetes afin de contrôler la communication de pod à pod:

apiVersion:networking.k8s.io/v1kind:NetworkPolicymetadata:
  name:allow-iam-webgateway
  namespace:app1spec:
  podSelector:
    matchLabels:
      app.kubernetes.io/component:webgateway
  policyTypes:
    -Ingress
  ingress:
    -ports:
        -protocol:TCP
          port:443

 

Ces stratégies garantissent que:

  • Les pods IRIS n'acceptent que les connexions provenant de sources autorisées (passerelle Web, IAM)
  • Les pods IAM n'acceptent que les connexions provenant du contrôleur Ingress
  • Les pods de passerelle Web n'acceptent que les connexions provenant d'IAM

Cette approche de sécurité réseau à plusieurs niveaux crée des périmètres d'isolation qui contiennent les violations de sécurité potentielles et limitent les mouvements latéraux au sein de l'environnement d'application.


Niveau 3: Sécurité des API avec IAM d'InterSystems

Au cœur de notre architecture de sécurité se trouve IAM d'InterSystems , une solution de gestion des API puissante basée sur Kong. Ce composant fournit des fonctionnalités de sécurité essentielles, notamment l'authentification, l'autorisation, la limitation du débit et la validation des requêtes.

3.1 Aperçu d'IAM d'InterSystems

IAM d'InterSystems sert de passerelle API pour toutes les requêtes adressées aux services IRIS, garantissant que seul le trafic autorisé et légitime atteint votre application. Dans notre implémentation, IAM est déployé en tant que StatefulSet au sein du même cluster Kubernetes que les instances IRIS, ce qui permet une intégration transparente tout en maintenant l'isolation des préoccupations.

La passerelle IAM est configurée avec une terminaison TLS/SSL et n'est exposée que par des points de terminaison sécurisés. Toutes les communications entre IAM et la passerelle Web IRIS sont cryptées, ce qui garantit la confidentialité des données en transit.

3.2 Configuration avancée de la limitation des taux

Afin de vous protéger contre les attaques par déni de service et l'utilisation abusive de l'API, nous avons mis en place une limitation avancée des taux via le rate-limiting-advanced plugind'IAM. Cette configuration utilise Redis comme magasin backend pour suivre les taux de requêtes sur les instances IAM distribuées.

{ "name": "rate-limiting-advanced", "config": { "identifier": "ip", "strategy": "redis", "window_type": "sliding", "limit": [2000, 3000], "window_size": [60, 60], "redis": { "host": "my-release-redis-master.default.svc.cluster.local", "port": 6379, "timeout": 2000, "keepalive_pool_size": 30 }, "error_message": "API rate limit exceeded" } }  

Cette configuration fournit deux niveaux de limitation des taux:

  • Niveau 1: 2,000 requêtes par minute avec une fenêtre glissante
  • Niveau 2: 3,000 requêtes par minute avec une fenêtre glissante

L'approche par fenêtre glissante fournit une limitation des taux plus précise que les fenêtres fixes, empêchant ainsi les pics de trafic aux périmètres des fenêtres. Lorsqu'un client dépasse ces limites, il reçoit un code d'état 429 accompagné d'un message d'erreur personnalisé.

3.3 Gestion sécurisée des sessions

Pour les applications nécessitant des sessions utilisateur, nous avons configuré le plugin de session IAM avec des paramètres sécurisés afin d'empêcher le détournement de session et de maintenir un cycle de vie approprié à la session:

{ "name": "session", "config": { "secret": "REDACTED", "cookie_secure": true, "cookie_same_site": "Strict", "cookie_http_only": true, "idling_timeout": 900, "absolute_timeout": 86400, "rolling_timeout": 14400 } }

Les principales fonctionnalités de sécurité mises en œuvre sont les suivantes:

  • Uniquement des cookies HTTP: Cela empêche JavaScript d'accéder aux cookies de session, ce qui atténue les attaques XSS
  • Indicateur de sécurité: Assure que les cookies ne sont envoyés que via des connexions HTTPS
  • Restriction au même site: empêche les attaques CSRF en limitant l'utilisation des cookies aux requêtes provenant du même site
  • Plusieurs mécanismes de timeout:
    • Timeout d'inactivité (15 minutes): Met fin aux sessions après une période d'inactivité
    • Timeout glissant (4 heurs): Nécessite une réauthentification périodique
    • Timeout absolu (24 heurs): Durée maximale de la session, quelle que soit l'activité

3.4 Validation des requêtes pour la sécurisation des entrées

Afin de nous protéger contre les attaques par injection et les requêtes malformées, nous avons mis en place une validation de requêtes stricte à l'aide du plugin de validation des requêtes IAM. Cela est particulièrement important pour sécuriser le broker CSP, qui est un composant essentiel chargé de gérer la communication client-serveur dans les applications InterSystems.

{ "name": "request-validator", "config": { "version": "kong", "body_schema": [ { "RequestParam": { "type": "integer", "required": true, "between": [1, 10] } }, { "EventType": { "type": "string", "required": true, "match": "^[a-zA-Z0-9$_]{100}$" } }, { "SessionID": { "type": "string", "required": true, "match": "^00b0[a-zA-Z0-9]{40}$" } } ], "verbose_response": true, "allowed_content_types": ["application/x-www-form-urlencoded"] } } 

Cette configuration impose des règles de validation rigoureuses:

  • Les champs de saisie doivent correspondre exactement aux types de données et aux contraintes
  • Les entrées de chaîne doivent correspondre à des modèles d'expressions régulières spécifiques
  • Les types de contenu autorisés sont les seuls acceptés

Le broker CSP est particulièrement sensible, car il sert de canal de communication entre les navigateurs clients et le serveur IRIS. En validant toutes les requêtes au niveau IAM avant qu'elles n'atteignent le broker, nous créons une barrière de sécurité supplémentaire qui protège contre les requêtes malformées ou malveillantes ciblant ce composant critique. Lorsqu'une requête échoue à la validation, l'IAM renvoie une réponse d'erreur détaillée qui aide à identifier le problème de validation sans révéler d'informations sensibles sur vos systèmes backend.

3.5 Configuration d'adresses IP fiables/p>

Pour renforcer encore davantage la sécurité, l'IAM est configuré pour reconnaître les proxys fiables et déterminer correctement les adresses IP des clients:

{ "trusted_ips": [ "10.0.0.0/24", "10.1.0.0/24", "10.0.3.0/24" ], "real_ip_header": "X-Forwarded-For", "real_ip_recursive": "on" }

Cette configuration garantit que:

  • La limitation du taux identifie correctement les adresses IP des clients, même via des proxys
  • Les règles de sécurité utilisant l'identification IP fonctionnent correctement
  • Les journaux d'accès enregistrent les adresses IP réelles des clients plutôt que celles des proxys

En implémentant ces fonctionnalités de sécurité avancées dans InterSystems IAM, nous avons créé un niveau de sécurité API robuste qui complète les mesures de sécurité périmétrique et réseau tout en protégeant les niveaux application et base de données contre le trafic malveillant ou excessif.


Niveau 4 : Sécurité des applications avec renforcement de la passerelle Web

Le quatrième niveau de notre architecture de sécurité se concentre sur le renforcement de la passerelle Web InterSystems, qui sert d'interface entre la passerelle IAM API et la base de données IRIS.

4.1 Configuration de la passerelle Web dans Kubernetes

TLa passerelle Web est déployée dans le cadre de la ressource personnalisée IrisCluster, avec une configuration spécifique axée sur la sécurité:

webgateway:

  image:containers.intersystems.com/intersystems/webgateway-nginx:2023.3
  type:nginx
  replicas:2
  applicationPaths:
    -/csp/app1
    -/csp/app2
    -/app3
    -/csp/app4
    -/app5
    -/csp/bin
  alternativeServers:LoadBalancing
  loginSecret:
    name:iris-webgateway-secret

Cette configuration limite la passerelle Web à la prise en charge de chemins d'accès spécifiques aux applications, ce qui réduit la surface d'attaque en empêchant l'accès aux points de terminaison non autorisés.

4.2 Renforcement de la sécurité de CSP.ini

La configuration CSP.ini de la passerelle Web est renforcée par plusieurs mesures de sécurité:

[SYSTEM]No_Activity_Timeout=480System_Manager=127.0.0.1Maximum_Logged_Request_Size=256KMAX_CONNECTIONS=4096Server_Response_Timeout=60Queued_Request_Timeout=60Default_Server=IRIS[APP_PATH:/app]Alternative_Servers=LoadBalancingAlternative_Server_0=1~~~~~~server-compute-0Response_Size_Notification=ChunkedTransferEncodingandContentLengthKeepAlive=NoActionGZIP_Compression=EnabledGZIP_Exclude_File_Types=jpeggificopnggzzipmp3mp4tiffGZIP_Minimum_File_Size=500

 

Les principales fonctionnalités de sécurité de cette configuration sont les suivantes:

  1. Gestionnaire de système désactivé: L'interface du gestionnaire de système est désactivée, sauf pour localhost
  2. Configuration manuelle uniquement: La configuration automatique est désactivée pour empêcher toute modification non autorisée
  3. Restrictions d'accès aux chemins: Chaque chemin d'application a des paramètres de sécurité spécifiques
  4. Mise en œuvre de l'authentification: AutheEnabled=64 impose l'authentification
  5. Timeout de session: Timeout de session de 15 minutes conformément aux paramètres IAM
  6. Les noms CSP verrouillés: Empêche les attaques transversales en verrouillant les noms CSP

4.3 Configuration avancée de la sécurité Nginx

Notre implémentation utilise une configuration Nginx fortement renforcée pour la passerelle Web, qui fournit plusieurs niveaux de défense:

# Définition d'une liste blanche à l'aide d'une carte

map $request_uri $whitelist_uri {

    default 0;

    "~^/app/.*$" 1;

    "~^/app/.*\.(csp|css|ico|js|png|woff2|ttf|jpg|gif)$" 1;

    "~^/csp/broker/cspxmlhttp.js$" 1;

    "~^/csp/broker/cspbroker.js$" 1;

    "~^/csp/app/.*$" 1;

    "~^/csp/bin/Systems/Module.cxw.*$" 1;

}



# Blocage global d'URI spécifiques
map $request_uri $block_uri {

    default 0;

    "~*%25login" 1;

    "~*%25CSP\.PasswordChange\.cls" 1;

    "~*%25ZEN\.SVGComponent\.svgPage" 1;

}



# Pages d'erreur personnalisées
error_page 403 /403.html;



# Application de la liste blanche d'URI
if ($whitelist_uri = 0) {

    return 403;

}



# Interdirction d'accès aux types de fichiers interdits
location ~* \.(ppt|pptx)$ {

    deny all;

    return 403;

}



# Interdiction d'accès aux URI bloqués
if ($block_uri) {

    return 403;

}



# Journalisation complète for security analysis
log_format security '$real_client_ip - $remote_user [$time_local] '

                   '"$request" $status $body_bytes_sent '

                   '"$http_referer" "$http_user_agent" '

                   '"$http_x_forwarded_for" "$request_body"';

Cette configuration met en œuvre plusieurs commandes de sécurité essentielles:

  1. Liste blanche d'URI: Seuls les chemins explicitement autorisés sont accessibles
  2. Blocage des chemins dangereux: Blocage automatique de l'accès aux points de terminaison dangereux
  3. Blocage des types de fichiers à risque: Cela empêche l'accès aux types de fichiers potentiellement dangereux
  4. Journalisation sécurisée: Journalisation détaillée de toutes les requêtes à des fins d'analyse
  5. Extraction de l'adresse IP client: Extraction correcte des adresses IP réelles des clients à partir des en-têtes X-Forwarded-For
  6. Pages d'erreur personnalisées: Réponses d'erreur standardisées qui ne divulguent pas d'informations sur le système

De plus, nous mettons en œuvre des en-têtes de sécurité renforcés et des limites de requêtes:

# Les en-têtes de sécurité

add_header X-XSS-Protection "1; mode=block" always;

add_header X-Content-Type-Options "nosniff" always;

add_header X-Frame-Options "SAMEORIGIN" always;

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

# Limites de taille des tampons et des requêtes

client_max_body_size 50M;

client_body_buffer_size 128k;

client_header_buffer_size 1k;

large_client_header_buffers 4 4k;

# Sécurité SSL/TLS

ssl_protocols TLSv1.2 TLSv1.3;

ssl_prefer_server_ciphers on;

ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';

Ces paramètres protègent contre les menaces suivantes:

  • Script inter-sites (XSS)
  • Attaques par confusion de types MIME
  • Clickjacking
  • Attaques par rétrogradation SSL
  • Tentatives de débordement de mémoire tampon
  • Attaques à charge utile importante

4.4 Configuration TLS

La passerelle Web est configurée pour utiliser des paramètres TLS modernes, garantissant ainsi une communication sécurisée:

tls:     

  webgateway:  secret:    secretName:iris-tls-secret

Notre implémentation TLS garantit:

  • Seuls les protocoles TLS 1.2+ sont autorisés
  • Des suites de chiffrement robustes avec confidentialité persistante sont renforcées
  • Les certificats sont correctement validés
  • La gestion des sessions est sécurisée

En mettant en œuvre ce dispositif complet de renforcement de la sécurité de la passerelle Web, nous créons un niveau de sécurité robuste qui protège la base de données IRIS contre les accès non autorisés et les vulnérabilités courantes des applications Web.

Niveau 5: Sécurité des bases de données dans les clusters IRIS

Le dernier niveau de notre architecture de sécurité vise à sécuriser la base de données IRIS elle-même, afin de garantir la protection des données même si tous les niveaux précédents sont compromis.

5.1 Configuration sécurisée d'IrisCluster avec l'Opérateur Kubernetes d'InterSystems (IKO)

Le cluster IRIS est déployé à l'aide de la définition de ressource personnalisée IrisCluster fournie par l'opérateur InterSystems Kubernetes (IKO), avec une configuration axée sur la sécurité:

apiVersion:intersystems.com/v1alpha1kind:IrisClustermetadata:
  name:example-app
  namespace:example-namespacespec:
  tls:     

    common:
      secret:
        secretName:iris-tls-secret
    mirror:
      secret:
        secretName:iris-tls-secret
    ecp:
      secret:
        secretName:iris-tls-secret
  topology:     

    data:
      image:containers.intersystems.com/intersystems/iris:2023.3
      preferredZones:
        -region-1a
        -region-1b
      mirrored:true
      podTemplate:
        spec:
          securityContext:
            runAsUser:51773  # irisowner
            runAsGroup:51773
            fsGroup:51773
      irisDatabases:
        -name:appdata
          mirrored:true
          ecp:true
      irisNamespaces:
        -name:APP
          routines:appdata
          globals:appdata
    compute:
      image:containers.intersystems.com/intersystems/iris:2023.3
      replicas:1
      compatibilityVersion:"2023.3.0"
      webgateway:
        image:containers.intersystems.com/intersystems/webgateway-nginx:2023.3
        replicas:1
        type:nginx
        applicationPaths:
          -/csp/sys
          -/csp/bin
          -/api/app
          -/app
    iam:
      image:containers.intersystems.com/intersystems/iam:3.4
    arbiter:
      image:containers.intersystems.com/intersystems/arbiter:2023.3
      preferredZones:
        -region-1c

Notre déploiement IKO comprend plusieurs fonctionnalités de sécurité essentielles:

  1. Cryptage TLS: Toutes les communications entre les instances IRIS sont cryptées à l'aide du protocole TLS
  2. Mise en miroir de la base de données: Haute disponibilité avec mise en miroir synchronisée garantissant l'intégrité des données
  3. Exécution non root: IRIS s'exécute en tant qu'utilisateur irisowner sans privilèges
  4. Sécurité ECP: Les connexions Enterprise Cache Protocol sont sécurisées avec TLS
  5. Répartition par zone: Les composants sont répartis entre plusieurs zones de disponibilité pour assurer la tolérance aux pannes
  6. Isolation des ressources: Séparation nette entre les données et les nœuds de calcul
  7. Espaces de noms IRIS: Espaces de noms correctement configurés et mappés à des bases de données sécurisées
  8. Nœud arbitre: Nœud arbitre dédié dans une zone de disponibilité distincte

5.2 Paramètres de sécurité de la base de données IRIS

Au sein de la base de données IRIS, les meilleures pratiques en matière de sécurité comprennent la mise en œuvre de plusieurs paramètres de sécurité clés:

  1. Authentification déléguée: Configuration IRIS pour utiliser des mécanismes d'authentification externes pour la gestion centralisée des identités
  2. Journalisation des audits: Activation d'un audit complet pour les événements liés à la sécurité, tels que les connexions, les modifications de configuration et l'augmentation des privilèges
  3. Sécurité du système: application des paramètres de sécurité au niveau du système conformément aux normes de l'industrie

Ces pratiques garantissent une gestion centralisée de l'authentification, la journalisation de toutes les activités liées à la sécurité à des fins d'analyse et la conformité du système aux normes de configuration sécurisées.

5.3 Sécurité basée sur les ressources IRIS

IRIS fournit un cadre de sécurité robuste basé sur les ressources et les rôles qui permet un contrôle d'accès très précis. Ce cadre peut être utilisé pour mettre en œuvre le principe du moindre privilège, en accordant aux utilisateurs et aux services uniquement les autorisations dont ils ont besoin pour exercer leurs fonctions.

Modèle de sécurité basé sur les ressources

Le modèle de sécurité basé sur les ressources d'IRIS comprend:

  1. Ressources: Objets sécurisés tels que les bases de données, les services, les applications et les opérations systèmes
  2. Autorisations: Différents niveaux d'accès aux ressources (lecture, écriture, utilisation)
  3. Rôles: Ensembles d'autorisations sur les ressources qui peuvent être attribués aux utilisateurs
  4. Utilisateurs: Comptes auxquels des rôles sont attribués et qui peuvent se connecter au système

Ce modèle permet aux administrateurs de sécurité de créer une structure de sécurité qui restreint l'accès en fonction des tâches et des besoins. Par exemple:

  • Les administrateurs de bases de données peuvent avoir un accès complet aux ressources de la base de données, mais un accès limité aux ressources de l'application
  • Les utilisateurs de l'application peuvent avoir accès uniquement à certaines fonctions spécifiques de l'application
  • Les comptes de service pour les intégrations peuvent avoir des autorisations restreintes adaptées à leurs besoins spécifiques

Documentation InterSystems

La mise en œuvre de la sécurité basée sur les rôles dans IRIS est bien documentée dans la documentation officielle d'InterSystems:

En tirant parti du cadre de sécurité intégré d'IRIS, les organisations peuvent créer un modèle de sécurité respectant le principe du moindre privilège, ce qui réduit considérablement le risque d'accès non autorisé ou d'augmentation des privilèges.

5.4 Cryptage des données

Les fichiers de la base de données IRIS sont cryptés à l'aide du cryptage AWS EBS au repos avec des clés KMS gérées par l'utilisateur:

kind:StorageClassapiVersion:storage.k8s.io/v1metadata:  name:iris-ssd-storageclassprovisioner:kubernetes.io/aws-ebsparameters:  type:gp3  encrypted:"true"volumeBindingMode:WaitForFirstConsumerallowVolumeExpansion:true

Le cluster EKS est configuré pour utiliser des volumes EBS chiffrés pour tout le stockage persistant, garantissant ainsi que les données inactives sont protégées par un chiffrement AES-256.

5.5 Sauvegarde et reprise après incident

Pour protéger contre la perte de données et garantir la continuité des activités de nos clients, notre architecture met en œuvre les mesures suivantes:

  1. Mise en miroir des journaux: Les journaux IRIS sont stockés sur des volumes distincts et mis en miroir
  2. Sauvegardes automatisées: Sauvegardes régulières vers des buckets S3 cryptés
  3. Réplication AZ croisée: Les données critiques sont répliquées vers une zone de disponibilité (AZ) AWS secondaire

Cette approche garantit que même en cas de panne catastrophique ou d'incident de sécurité, les données peuvent être récupérées avec un minimum de pertes.

Guide de mise en œuvre

Pour mettre en œuvre cette architecture de sécurité à plusieurs niveaux pour vos propres déploiements IRIS sur AWS, suivez ces étapes générales:

Étape 1 : Configuration de l'infrastructure AWS

  1. Créez un VPC avec des sous-réseaux privés et publics dans plusieurs zones de disponibilité
  2. Configurez des passerelles NAT pour la connectivité sortante à partir des sous-réseaux privés
  3. Créez des groupes de sécurité avec des règles d'entrée et de sortie appropriées
  4. Déployez un cluster EKS dans des sous-réseaux privés

Étape 2: Configuration des services de sécurité AWS

  1. Créez une liste de contrôle d'accès Web AWS WAF avec les ensembles de règles appropriés
  2. Configurez la distribution CloudFront avec l'association WAF
  3. Configurez AWS ALB pour Kubernetes Ingress

Étape 3 : Déployez l'IAM d'InterSystems

  1. Créez les informations secrètes Kubernetes nécessaires pour les certificats et les informations d'identification
  2. Déployez l'IAM StatefulSet à l'aide de l'opérateur IrisCluster
  3. Configurez les plugins de sécurité IAM (limitation du taux, gestion des sessions, validation des requêtes)

Étape 4 : Déploiement et sécurisation du cluster IRIS

  1. Créez une ressource personnalisée IrisCluster avec des configurations de sécurité
  2. Configurez TLS pour toutes les communications
  3. Déployez la passerelle Web avec une configuration renforcée
  4. Configurez la mise en miroir de la base de données et la sécurité ECP

Étape 5 : Mise en œuvre de la surveillance et de la journalisation

  1. Configurez la journalisation centralisée avec ElasticSearch
  2. Configurez la surveillance de la sécurité avec Datadog
  3. Mettez en œuvre des alertes pour les événements de sécurité
  4. Activez la journalisation d'audit IRIS

Surveillance et réponse aux incidents

Une architecture de sécurité robuste doit inclure des capacités de surveillance continue et de réponse aux incidents. Notre mise en œuvre comprend:

6.1 Surveillance de la sécurité

L'architecture comprend une surveillance complète à l'aide de Datadog et ElasticSearch:

  1. Analyse des journaux en temps réel: Tous les composants envoient leurs journaux à un cluster ElasticSearch centralisé
  2. Tableaux de bord de sécurité: Les tableaux de bord Datadog visualisent les mesures de sécurité et les anomalies
  3. Alertes automatisées: Des alertes sont générées en cas d'activités suspectes ou de violations de la sécurité

6.2 Réponse aux incidents

Un processus défini de réponse aux incidents garantit une réaction rapide aux événements de sécurité:

  1. Détection: Détection automatisée des incidents de sécurité grâce à la surveillance
  2. Classification: Les incidents sont classés par gravité et par type
  3. Contention: procédures visant à contenir les incidents, y compris les réponses automatisées
  4. Éradication: Mesures visant à éliminer la menace et à rétablir la sécurité
  5. Récupération: Procédures de restauration du fonctionnement normal
  6. Leçons apprises: Analyse post-incident pour améliorer le niveau de sécurité

Considérations relatives aux performances

La mise en œuvre de plusieurs niveaux de sécurité peut avoir un impact sur les performances. Notre architecture répond à ce problème grâce aux éléments suivants:

7.1 Stratégies de mise en cache

  1. Mise en cache CloudFront: Le contenu statique est mis en cache à la périphérie
  2. Mise en cache de la passerelle API: IAM implémente la mise en cache des réponses pour les points de terminaison appropriés
  3. Mise en cache de la passerelle Web: Les pages CSP sont mises en cache lorsque cela est possible

7.2 Équilibrage de charge

  1. Déploiement multizone de disponibilité (AZ): Les services sont répartis entre plusieurs zones de disponibilité
  2. Mise à l'échelle horizontale: Les composants peuvent être mis à l'échelle horizontalement en fonction de la charge
  3. Paramètres d'affinité: L'anti-affinité des pods garantit une distribution adéquate

7.3 Mesures de performance

Au cours de la mise en œuvre, nous avons observé les impacts suivants sur les performances:

  1. Latence: La latence moyenne des requêtes n'a augmenté que de 20 à 30 ms malgré toutes les niveaux de sécurité
  2. Débit: Le système peut traiter plus de 2 000 demandes par seconde avec toutes les mesures de sécurité
  3. Utilisation des ressources: Les composants de sécurité supplémentaires ont augmenté l'utilisation du processeur d'environ 15%

Ces mesures démontrent qu'une architecture de sécurité robuste peut être mise en œuvre sans dégradation significative des performances.

Conclusion

L'architecture de sécurité à plusieurs niveaux décrite dans cet article fournit une protection complète pour les déploiements InterSystems IRIS sur AWS. En mettant en œuvre des contrôles de sécurité à chaque niveau, du périmètre du réseau à la base de données, nous créons une stratégie de défense en profondeur qui réduit considérablement le risque d'attaques réussies.

Les principaux avantages de cette approche sont les suivants:

  1. Protection complète: Plusieurs niveaux fournissent une protection contre un large éventail de menaces
  2. Défense en profondeur: Si une mesure de sécurité échoue, les autres restent en place
  3. Évolutivité: l'architecture est scalable horizontalement pour gérer une charge accrue
  4. Simplicité de gestion: L'approche "infrastructure en tant que code" rend les contrôles de sécurité reproductibles et versionnables
  5. Conformité: L'architecture aide à respecter les exigences réglementaires en matière de protection des données

En tirant parti des services de sécurité AWS, d'IAM d'InterSystems et des configurations IRIS sécurisées, les organisations peuvent créer des applications sécurisées et hautement performantes tout en protégeant les données sensibles contre les menaces émergentes.

Références

  1. Documentation InterSystems: Guide de sécurité IRIS
  2. Meilleures pratiques en matière de sécurité AWS: Pilier de la sécurité AWS
  3. Sécurité Kubernetes: Guide des meilleures pratiques EKS
  4. Sécurité API OWASP: Les 10 principaux risques liés à la sécurité API
  5. Registre de conteneurs InterSystems: containers.intersystems.com
0
0 17
Article Sylvain Guilbaud · Mai 30, 2025 3m read

Kong fournit en open source un outil de gestion de ses configurations (écrit en Go), appelé decK (pour declarative Kong)

  • Vérifiez que decK reconnaît votre installation Kong Gateway via deck gateway ping
deck gateway ping   
Successfully connected to Kong!
Kong version:  3.4.3.11
  • Exporter la configuration de Kong Gateway dans un fichier "kong.yaml" via deck gateway dump
deck gateway dump -o kong.yaml
  • Après avoir modifié les adresses IP dans le fichier kong.yaml, afficher les différences via deck gateway diff
0
0 25
InterSystems officiel Adeline Icard · Août 12, 2024

Les versions 2.8.4.11 et 3.4.3.11 d'InterSystems API Manager (IAM) sont désormais disponibles. Il s'agit des dernières versions des deux versions d'IAM prises en charge à long terme. Ces versions contiennent des correctifs importants et tous les clients sont encouragés à effectuer une mise à niveau.

Les clients d'IAM 3.0 ou 3.2 sont encouragés à effectuer une mise à niveau vers la version 3.4.3.11, car la prise en charge de ces versions prendra bientôt fin.

0
0 34
InterSystems officiel Adeline Icard · Juil 22, 2024

Les versions 2.8.4.10 et 3.4.3.10 d'InterSystems API Manager (IAM) sont désormais généralement disponibles. Il s'agit des dernières versions des deux versions d'IAM prises en charge à long terme. Ces versions contiennent des correctifs importants et tous les clients sont encouragés à effectuer la mise à niveau.

Les clients utilisant IAM 3.0 ou 3.2 sont encouragés à passer à la version 3.4.3.10, car la prise en charge de ces versions prendra bientôt fin.

0
0 38
Question Cyril Grosjean · Fév 26, 2024

Bonjour,

Je cherche à pouvoir activer l'authentification sur IAM. J'ai activé via docker le RBAC via ces lignes :

KONG_ENFORCE_RBAC:'on'# Activation de RBACKONG_ADMIN_GUI_AUTH:basic-authKONG_ADMIN_GUI_SESSION_CONF:'{"secret":"SYS","storage":"kong","cookie_secure":false}'

J'ai également créé avec des requêtes curl un "consummer" :

curl -i -X POST http://localhost:8001/consumers \
  --data "username=superadmin"
curl -i -X POST http://localhost:8001/consumers/superadmin/basic-auth \
  --data "username=superadmin" \
  --data "password=superpassword"
4
0 94
Article Pierre LaFay · Jan 3, 2024 8m read

Expérience et retour d'expérience du cours en ligne "Hands-On with InterSystems API Manager for Developers

Avec mes connaissances de base du conteneur Docker et de l'API REST, j'aimerais faire mon premier essai d'utilisation du gestionnaire d'API InterSystems pour prendre le contrôle des API et des microservices. J'ai suivi ce cours en ligne en utilisant mon instance IRIS locale comme hôte (système d'exploitation Windows) et IAM exécuté sur une machine virtuelle Linux (invité).

0
0 75
InterSystems officiel Adeline Icard · Avr 4, 2023

Version IAM 3.2

InterSystems API Manager (IAM) version 3.2.1 est désormais généralement disponible. En plus des corrections de bogues et des améliorations mineures, IAM 3.2 ajoute de nouveaux plug-ins susceptibles d'intéresser les clients IRIS.

  • Validation OAS (oas-validation)
    • Validez les requêtes et les réponses HTTP en fonction d'une spécification d'API OpenAPI 3.0 ou Swagger.
  • SAML (saml)
    • Fournit l'authentification et l'autorisation SAML v2.0 entre un fournisseur de services (Kong Gateway) et un fournisseur d'identité (IdP).
  • Protection contre les menaces XML (xml-threat-protection)
    • Ce nouveau plugin vous permet de réduire le risque d'attaques XML en vérifiant la structure des charges utiles XML. Cela valide la complexité maximale (profondeur de l'arbre), la taille maximale des éléments et des attributs.
  • AppDynamics (app-dynamics)
    • Intégrez Kong Gateway à la plateforme AppDynamics APM.
  • Déchiffrement JWE (jwe-decrypt)
    • Permet de déchiffrer un jeton entrant (JWE) dans une requête.
0
0 56
Article Lorenzo Scalese · Juin 18, 2022 5m read

InterSystems API Management (IAM) - c'est une nouvelle fonctionnalité de la plate-forme de données InterSystems IRIS, qui vous permet de surveiller, de contrôler et de gérer le trafic vers et à partir des API basées sur le Web au sein de votre infrastructure informatique. Au cas où vous l'auriez manqué, voici le lien vers l'annonce. Et voici un article expliquant comment commencer à travailler avec IAM.

Dans cet article, nous allons utiliser InterSystems API Management pour assurer l'équilibrage de charge d'une API.

Dans notre cas, nous avons 2 instances InterSystems IRIS avec /api/atelier REST API que nous voulons publier pour nos clients.

Il y a de nombreuses raisons différentes pour lesquelles nous pourrions vouloir faire cela, par exemple :

  • Équilibrage de la charge pour répartir la charge de travail entre les serveurs.
  • Déploiement bleu-vert : nous avons deux serveurs, l'un "prod", l'autre "dev" et nous pouvons vouloir passer de l'un à l'autre.
  • Déploiement canary: nous pourrions publier la nouvelle version sur un seul serveur et y transférer 1% des clients.
  • Configuration de haute disponibilité
  • etc.

Pourtant, les mesures que nous devons prendre sont assez similaires.

Conditions préalables

  • 2 instances InterSystems IRIS
  • L'instance InterSystems API Managemen  

Allons-y

Voici ce que nous devons faire :

1. Créer un flux ascendant.

Un flux ascendant représente un nom d'hôte virtuel et peut être utilisé pour équilibrer la charge des demandes entrantes sur plusieurs services (cibles). Par exemple, un flux ascendant nommé service.v1.xyz recevrait des demandes pour un service dont l'hôte est service.v1.xyz. Les requêtes pour ce service seront envoyées par procuration aux cibles définies dans l'amont.

Un flux ascendant comprend également un vérificateur de santé, qui peut activer et désactiver les cibles en fonction de leur capacité ou de leur incapacité à répondre aux demandes.

Pour commencer :

  • Ouvrir le portail d'administration IAM
  • Allez dans Workspaces
  • Choisissez votre espace de travail
  • Ouvrez les flux ascendants (Upstreams)
  • Cliquez sur le bouton "New Upstream"

Après avoir cliqué sur le bouton "New Upstream", vous verrez apparaître un formulaire où vous pourrez saisir quelques informations de base sur le flux ascendant (il y a beaucoup d'autres propriétés) :

Saisissez nom - il s'agit d'un nom d'hôte virtuel que nos services utiliseraient. Il n'est pas lié aux enregistrements DNS. Je recommande de lui attribuer une valeur inexistante pour éviter toute confusion. Si vous voulez en savoir plus sur les autres propriétés, consultez la documentation. Sur la capture d'écran, vous pouvez voir que j'ai nommé de manière imaginative le nouveau flux ascendant comme myupstream.  

2. Créer des cibles.

Les cibles sont des serveurs backend qui exécutent les requêtes et renvoient les résultats au client. Allez dans Upstreams et cliquez sur le nom du flux ascendant que vous venez de créer (et NON sur le bouton de mise à jour) :

Vous verrez toutes les cibles existantes (aucune jusqu'à présent) et le bouton "Nouvelle cible". Cliquez dessus :

Ensuite, définissez une cible dans le nouveau formulaire. Seuls deux paramètres sont disponibles :

  • cible - hôte et port du serveur backend
  • Pondération - priorité relative donnée à ce serveur (plus de pondération - plus de demandes sont envoyées à cette cible)

J'ai ajouté deux cibles :

 

3. Créer un service

A présent que nous avons notre flux ascendant, nous devons lui envoyer des requêtes.  Pour cela, nous utilisons Service.
Les entités Service, comme leur nom l'indique, sont des abstractions de chacun de vos services en amont. Des exemples de services seraient un microservice de transformation des données, une API de facturation, etc. Nous allons créer un service ciblant notre instance IRIS, allez dans Services et cliquez sur le bouton "Nouveau service" :

Définissez les valeurs suivantes :

champvaleurdescription
nommyservicenom logique de ce service
hôtemyupstreamnom en amont
chemin/api/atelierchemin d'accès associé à une racine que nous voulons servir
protocolehttples protocoles que nous voulons supporter

Conservez les valeurs par défaut pour tout le reste (y compris le port : 80).

Après avoir créé le service, vous le verrez dans une liste de services. Copiez l'ID du service quelque part, nous en aurons besoin plus tard.

 

4. Créer un itinéraire

Les Itinéraires définissent les règles permettant de répondre aux demandes des clients. Chaque Itinéraire est associé à un Service, et un Service peut avoir plusieurs Itinéraires associés. Chaque demande correspondant à un Itinéraire donné sera transmise par proxy au Service qui lui est associé.

La combinaison des Itinéraires et des Services (et la séparation des préoccupations entre eux) offre un mécanisme de routage puissant avec lequel il est possible de définir des points d'entrée très fins dans l'IAM menant à différents services en amont de votre infrastructure.

Maintenant, créons un itinéraire. Allez dans le menu Routes et appuyez sur le bouton "New Route".

Définissez les valeurs dans le formulaire de création de l'Itinéraire :

champvaleurdescription
lien/api/atelierlien racine que nous voulons servir
protocolehttp les protocoles que nous voulons supporter
service.idguid de 3valeur de l'identifiant du service (guide de l'étape précédente)
 

Et c'est fini !

Envoyez une requête à http://localhost:8000/api/atelier/ (notez la barre oblique à la fin) et elle sera servie par l'un de nos deux backends.  

Conclusion

IAM offre une infrastructure de gestion des API hautement personnalisable, permettant aux développeurs et aux administrateurs de prendre le contrôle de leurs API.  

Liens

Question

Quelle fonctionnalité souhaitez-vous voir configurée avec IAM ?

0
0 87
Article Sylvain Guilbaud · Avr 19, 2022 2m read

Kong fournit en open source un outil de gestion de ses configurations (écrit en Go), appelé decK (pour declarative Kong)

  • Vérifiez que decK reconnaît votre installation Kong Gateway via deck ping
deck ping   
Successfully connected to Kong!
Kong version:  2.3.3.2-enterprise-edition
  • Exporter la configuration de Kong Gateway dans un fichier "kong.yaml" via deck dump
deck dump
  • Après avoir modifié le kong.yaml, afficher les différences via deck diff
0
0 182
Article Guillaume Rongier · Fév 28, 2022 38m read

alt

Cet article contient le matériel, les exemples, les exercices pour apprendre les concepts de base de IAM.

Toutes les ressources sont disponibles sur ce git : https://github.com/grongierisc/iam-training.

Les solutions sont dans la branche training.

Cet article couvre les sujets suivants :

1. Introduction

alt

1.1. Qu'est-ce que IAM ?

IAM signifie InterSystems API Manager, il est basé sur Kong Enterprise Edition.

Cela signifie que vous avez accès, en plus de l'édition Kong Open Source, au :

  • Portail gestionnaire
  • Portail des développeurs
  • Plugin avancé
    • Oauth2
    • Mise en cache
    • ...

alt

1.2. Qu'est-ce que la gestion d''API ?

La gestion des API est le processus de création et de publication d'interfaces de programmation d'applications (API) Web, d'application de leurs politiques d'utilisation, de contrôle de l'accès, d'entretien de la communauté d'abonnés, de collecte et d'analyse des statistiques d'utilisation et de production de rapports sur les performances. Les composants de gestion des API fournissent des mécanismes et des outils pour soutenir la communauté des développeurs et des abonnés.

alt

1.3. Portail IAM

Kong et IAM sont conçus comme des API d'abord, ce qui signifie que tout ce qui est fait dans Kong/IAM peut être fait par des appels REST ou le portail du gestionnaire.

Au cours de cet article, tous les exemples/exercices présenteront les deux de cette façon :

Portail IAMAPI Rest
altalt

1.4. Flux de cet article

Le but de cet article est d'utiliser IAM comme proxy d'une API rest IRIS.

La définition de cette API rest peut être trouvée ici :

http://localhost:52773/swagger-ui/index.html#/

ou ici

https://github.com/grongierisc/iam-training/blob/training/misc/spec.yml

Commencez cet article avec la branche principale.

A la fin de l'article, vous devriez avoir le même résultat que la branche d'entraînement.

2. Installation

alt

2.1. Que devez-vous installer ?

2.2. Comment IAM fonctionne avec IRIS

Au démarrage de Kong/IAM, le conteneur vérifie la licence Kong/IAM avec un appel curl.

Le point de terminaison de cet appel est une API REST sur le conteneur IRIS.

Info : la licence Kong est incorporée dans celle d'IRIS.

alt

2.3. Configuration

Clonez Git ce dépôt.


git clone https://github.com/grongierisc/iam-training

Exécutez l'API rest initiale :


docker-compose up

Testez-la :

http://localhost:52773/swagger-ui/index.html#/

Identifiant/mot de passe : SuperUser/SYS

2.4. Installer IAM

2.4.1. Image Iris

Vous devez d'abord passer de l'édition communautaire à une édition sous licence.

Pour ce faire, vous devez configurer votre accès à InterSystems Container Registry pour télécharger les images IRIS à accès limité.

Jetez un œil à la Présentation d'InterSystems Container Registry dans la Communauté des développeurs.

  • Connectez-vous à https://containers.intersystems.com/ en utilisant vos informations d'identification du WRC et obtenez un jeton.
  • Configurez la connexion docker sur votre ordinateur :
docker login -u="user" -p="token" containers.intersystems.com
  • Obtenez l'image IRIS InterSystems :
docker pull containers.intersystems.com/intersystems/irishealth:2020.4.0.524.0

2.4.2. Image IAM

Dans la distribution logicielle WRC :

  • Composants > Téléchargez le fichier IAM-1.5.0.9-4.tar.gz, décompressez & untar puis chargez l'image :
docker load -i iam_image.tar

2.4.3. Mettre le fichier docker à jour

Remplacer l'édition communautaire d'IRIS par une édition sous licence.

  • containers.intersystems.com/intersystems/irishealth:2020.4.0.524.0
  • ajoutez iris.key dans le dossier key

Modifiez le dockerfile pour ajouter par-dessus cette partie

ARG IMAGE=containers.intersystems.com/intersystems/irishealth:2020.4.0.524.0
# Première étape
FROM $IMAGE as iris-iam
COPY key/iris.key /usr/irissys/mgr/iris.key
COPY iris-iam.script /tmp/iris-iam.script
RUN iris start IRIS \
&& iris session IRIS < /tmp/iris-iam.script \
&& iris stop IRIS quietly

# Seconde étape
FROM iris-iam

Cette partie va créer un dockerfile à plusieurs étapes.

  • la première étape consiste à permettre à IRIS de servir la licence IAM.
  • la deuxième étape est pour la compliation de l'API REST

Créez un nouveau fichier iris-iam.script pour compiler une nouvelle image IRIS afin d'activer le point de terminaison et l'utilisateur IAM.

zn "%SYS"
write "Création d'une application Web ...",!
set webName = "/api/iam"
set webProperties("Enabled") = 1
set status = ##class(Security.Applications).Modify(webName, .webProperties)
write:'status $system.Status.DisplayError(status)
write "Web application "_webName_" a été mis à jour !",!

set userProperties("Enabled") = 1
set userName = "IAM"
Do ##class(Security.Users).Modify(userName,.userProperties)
write "User "_userName_" a été mis à jour !",!
halt

2.4.4. Mettre le docker-compose à jour

Metez le fichier docker-compose à jour vers :

  • db
    • base de données postgres pour IAM
  • iam-migration
    • amorcer la base de données
  • iam
    • instance IAM réelle
  • un volume pour les données persistantes

Ajoutez cette partie à la fin du fichier docker-compose.

  iam-migrations:
    image: intersystems/iam:1.5.0.9-4
    command: kong migrations bootstrap up
    depends_on:
      - db
    environment:
      KONG_DATABASE: postgres
      KONG_PG_DATABASE: ${KONG_PG_DATABASE:-iam}
      KONG_PG_HOST: db
      KONG_PG_PASSWORD: ${KONG_PG_PASSWORD:-iam}
      KONG_PG_USER: ${KONG_PG_USER:-iam}
      KONG_CASSANDRA_CONTACT_POINTS: db
      KONG_PLUGINS: bundled,jwt-crafter
      ISC_IRIS_URL: IAM:${IRIS_PASSWORD}@iris:52773/api/iam/license
    restart: on-failure
    links:
      - db:db
  iam:
    image: intersystems/iam:1.5.0.9-4
    depends_on:
      - db
    environment:
      KONG_ADMIN_ACCESS_LOG: /dev/stdout
      KONG_ADMIN_ERROR_LOG: /dev/stderr
      KONG_ADMIN_LISTEN: '0.0.0.0:8001'
      KONG_ANONYMOUS_REPORTS: 'off'
      KONG_CASSANDRA_CONTACT_POINTS: db
      KONG_DATABASE: postgres
      KONG_PG_DATABASE: ${KONG_PG_DATABASE:-iam}
      KONG_PG_HOST: db
      KONG_PG_PASSWORD: ${KONG_PG_PASSWORD:-iam}
      KONG_PG_USER: ${KONG_PG_USER:-iam}
      KONG_PROXY_ACCESS_LOG: /dev/stdout
      KONG_PROXY_ERROR_LOG: /dev/stderr
      KONG_PORTAL: 'on'
      KONG_PORTAL_GUI_PROTOCOL: http
      KONG_PORTAL_GUI_HOST: '127.0.0.1:8003'
      KONG_ADMIN_GUI_URL: http://localhost:8002
      KONG_PLUGINS: bundled
      ISC_IRIS_URL: IAM:${IRIS_PASSWORD}@iris:52773/api/iam/license
    volumes: 
      - ./iam:/iam
    links:
      - db:db
    ports:
      - target: 8000
        published: 8000
        protocol: tcp
      - target: 8001
        published: 8001
        protocol: tcp
      - target: 8002
        published: 8002
        protocol: tcp
      - target: 8003
        published: 8003
        protocol: tcp
      - target: 8004
        published: 8004
        protocol: tcp
      - target: 8443
        published: 8443
        protocol: tcp
      - target: 8444
        published: 8444
        protocol: tcp
      - target: 8445
        published: 8445
        protocol: tcp
    restart: on-failure
  db:
    image: postgres:9.6
    environment:
      POSTGRES_DB: ${KONG_PG_DATABASE:-iam}
      POSTGRES_PASSWORD: ${KONG_PG_PASSWORD:-iam}
      POSTGRES_USER: ${KONG_PG_USER:-iam}
    volumes:
      - 'pgdata:/var/lib/postgresql/data'
    healthcheck:
      test: ["CMD", "pg_isready", "-U", "${KONG_PG_USER:-iam}"]
      interval: 30s
      timeout: 30s
      retries: 3
    restart: on-failure
    stdin_open: true
    tty: true
volumes:
  pgdata:

Ajoutez le fichier .env dans le dossier racine :

IRIS_PASSWORD=SYS

NB : Voici la définition des ports Kong :

PortProtocoleDescription
:8000HTTPPrend le trafic HTTP entrant des Consommateurs, et le transmet aux Services en amont.
:8443HTTPSReçoit le trafic HTTPS entrant des consommateurs et le transmet aux services en amont.
:8001HTTPAPI d'administration. Écoute les appels de la ligne de commande via HTTP.
:8444HTTPSAPI d'administration. Écoute les appels de la ligne de commande via HTTPS.
:8002HTTPKong Manager (GUI). Écoute le trafic HTTP.
:8445HTTPSKong Manager (GUI). Écoute le trafic HTTPS.
:8003HTTPPortail des développeurs. Écoute le trafic HTTP, en supposant que Portail des développeurs est activé.
:8446HTTPSPortail des développeurs. Écoute le trafic HTTPS, en supposant que Portail des développeurs est activé.
:8004HTTPPortail des développeurs /écoute le trafic HTTP, en supposant que le portail des développeurs est activé.
:8447HTTPSPortail des développeurs /écoute le trafic HTTPS, en supposant que le portail des développeurs est activé.

2.4.5. Option : add IRIS_PASSWARD comme .env

Pour des raisons de facilité d'utilisation (et peut-être de sécurité), vous pouvez utiliser le fichier .env dans le dockerfile IRIS.

Pour ce faire, modifiez le docker-compose avec ceci dans la partie service iris :

    build: 
      context: .
      dockerfile: dockerfile
      args: 
        - IRIS_PASSWORD=${IRIS_PASSWORD}

Et le dockerfile (deuxième ou première étape de la compilation) :

ARG IRIS_PASSWORD
RUN echo "${IRIS_PASSWORD}" > /tmp/password.txt && /usr/irissys/dev/Container/changePassword.sh /tmp/password.txt

2.4.6. Essayez !


docker-compose -f "docker-compose.yml" up -d --build

3. Premier service/route

alt

Vous vous souvenez comment fonctionne Kong/IAM ?

alt

Ici, nous compilerons :

  • un service
    • pour notre API crud
  • une route
    • pour accéder à ce service

3.1. Créer un service

Portail IAM API Rest

foo



# Créer un service

curl -i -X POST \
--url http://localhost:8001/services/ \
--data 'name=crud' \
--data 'url=http://iris:52773/crud/'

Par défaut, tout est accessible pour un utilisateur non authentifié.

3.2. Créer une route

Portail IAM API Rest

foo


# Créer une route

curl -i -X POST
--url http://localhost:8001/services/crud/routes
--data 'name=crud-route'
--data 'paths=/persons/*'
--data 'strip_path=false'

Que voyons-nous ici, pour créer une route nous avons besoin de :

  • son nom de service
  • un chemin ou les RegEx sont autorisées

3.3. Essayez !

API originale


# Obsolète


curl –i --location --request GET 'http://localhost:52773/crud/persons/all' \
--header 'Authorization: Basic U3VwZXJVc2VyOlNZUw=='

API proxy


# KONG


curl –i --location --request GET 'http://localhost:8000/persons/all' \
--header 'Authorization: Basic U3VwZXJVc2VyOlNZUw=='

Ce que nous voyons ici  :

  • Rien de nouveau du côté hérité.
  • Du côté kong :
    • Nous changeons le port
    • Le chemin correspond à la route
    • Nous devons toujours nous authentifier

4. Ensuite, allez plus loin avec le plugin

Pour aller plus loin, nous allons essayer d'auto-authentifier Kong au point de terminaison IRIS.

Pour ce faire, nous utiliserons un plugin, resquest-transformer.

alt

4.1. Ajouter un plugin au service

Portail IAM API Rest

foo


# Créer un plugin
curl -i -X POST \
--url http://localhost:8001/services/crud/plugins \
--data 'name=request-transformer' \
--data 'config.add.headers=Authorization:Basic U3VwZXJVc2VyOlNZUw==' \
--data 'config.replace.headers=Authorization:Basic U3VwZXJVc2VyOlNZUw=='

4.2. Essayez !


# Obsolète

**API originale**
curl –i --location --request GET 'http://localhost:52773/crud/persons/all' 

API proxy


# KONG


curl –i --location --request GET 'http://localhost:8000/persons/all' 

Ce que nous voyons ici  :

  • Erreur 401 sur l'API originale
  • Nous atteignons les données sans authentification

5. Troisièmement, ajoutez votre propre authentification

Ce que nous voulons réaliser ici est d'ajouter notre propre authentification sans aucun dérangement de l'API originale.

alt

5.1. Ajouter des consommateurs

Portail IAM API Rest

foo


# Ajouter un consommateur anonyme
curl -i -X POST \
--url http://localhost:8001/consumers/ \
--data "username=anonymous" \
--data "custom_id=anonymous"

foo


# Ajouter un utilisateur consommateur
curl -i -X POST \
--url http://localhost:8001/consumers/ \
--data "username=user" \
--data "custom_id=user"

5.2. Ajouter un plugin d'authentification basique

Portail IAM API Rest

foo


# Activer l'authentification de base pour le service
curl -i -X POST http://localhost:8001/routes/crud-route/plugins \
--data "name=basic-auth" \
--data "config.anonymous=5cc8dee4-066d-492e-b2f8-bd77eb0a4c86" \
--data "config.hide_credentials=false"

Où :

  • config.anonymous = uuid du consommateur anonyme

5.3. Ajouter un plugin ACL

Portail IAM API Rest

foo


# Activer ACL

curl -i -X POST http://localhost:8001/routes/crud-route/plugins
--data "name=acl"
--data "config.whitelist=user"

5.4. Configurer USER avec ACL et des identifiants

Portail IAM API Rest

foo


# Ajouter un groupe consommateur
curl -i -X POST \
--url http://localhost:8001/consumers/user/acls \
--data "group=user"
# Add consumer credentials
curl -i -X POST http://localhost:8001/consumers/user/basic-auth \
--data "username=user" \
--data "password=user"

5.5. Essayez !

API originale


# Obsolète


curl –i --location --request GET 'http://localhost:52773/crud/persons/all' \
--header 'Authorization:Basic dXNlcjp1c2Vy'


**API proxy **


# KONG

curl –i --location --request GET 'http://localhost:8000/persons/all' \
--header 'Authorization:Basic dXNlcjp1c2Vy'

6. Exercice, limitation du débit

  1. Activer un utilisateur non authentifié
  2. Limiter le débit à 2 appels par minutes pour un utilisateur non authentifié

6.1. Solution

  1. Activer un utilisateur non authentifié
Portail IAM API Rest

foo


# Ajouter un groupe consommateur

curl -i -X POST \
--url http://localhost:8001/consumers/anonymous/acls \
--data "group=user"
  1. Limiter le débit à 2 appels par minutes pour un utilisateur non authentifié
Portail IAM API Rest

foo


# Ajouter une limitation du débit consommateur
curl -i -X POST \
--url http://localhost:8001/consumers/anonymous/plugins \
--data "name=rate-limiting" \
--data "config.limit_by=consumer" \
--data "config.minute=2"

7. Portail des développeurs

alt

7.1. Vue d'ensemble

Le Portail des développeurs Kong fournit :

  • une source unique de vérité pour tous les développeurs
  • une gestion intuitive du contenu de la documentation
  • une intégration simplifiée des développeurs
  • un contrôle d'accès basé sur les rôles (RBAC)

alt

7.2. Activez-le !

Portail IAM API Rest

foo


curl -X PATCH http://localhost:8001/workspaces/default --data "config.portal=true"

7.3. Ajoutez votre première spécification

Portail IAM

foo

foo

API Rest


curl -X POST http://localhost:8001/default/files -F "path=specs/iam-training.yml" -F "contents=@misc/spec.yml"

7.4. Essayez !

http://localhost:8003/default/documentation/iam-training

Que s'est-il passé ?

Comment résoudre ce problème ?

7.5. Exercice

  1. Ajouter un plugin CORS à la route

7.5.1. Solution

Portail IAM API Rest

foo


# Activer CORS

curl -i -X POST http://localhost:8001/routes/crud-route/plugins \
--data "name=cors"

8. Portail développeur, partie deux, authentification

8.1. Activer l'authentification de base

Portail IAM Configuration de la session (JSON)

foo


{
    "cookie_secure": false,
    "cookie_name": "portal_session",
    "secret": "SYS",
    "storage": "kong"
}

L'authentification est maintenant activée pour le portail des développeurs.

8.2. Limiter l'accès

Par défaut, tout est accessible pour un utilisateur non authentifié.

Nous pouvons créer un rôle pour limiter certains accès.

Par exemple, limitons l'accès à la documentation de notre API CRUD.

8.2.1. Créer un rôle

Portail IAM API Rest

foo


# Activer le rôle

curl -i -X POST http://localhost:8001/default/developers/roles \
--data "name=dev"

8.2.2. Ajouter un rôle à la spec

Portail IAM

foo

API Rest


# Activer le rôle

curl 'http://localhost:8001/default/files/specs/iam-training.yml' -X PATCH -H 'Accept: application/json, text/plain, */*'  --compressed -H 'Content-Type: application/json;charset=utf-8' -H 'Origin: http://localhost:8002' -H 'Referer: http://localhost:8002/default/portal/permissions/' --data-raw $'{"contents":"x-headmatter:\\n  readable_by:\\n    - dev\\nswagger: \'2.0\'\\ninfo:\\n  title: InterSystems IRIS REST CRUD demo\\n  description: Demo of a simple rest API on IRIS\\n  version: \'0.1\'\\n  contact:\\n    email: apiteam@swagger.io\\n  license:\\n    name: Apache 2.0\\n    url: \'http://www.apache.org/licenses/LICENSE-2.0.html\'\\nhost: \'localhost:8000\'\\nbasePath: /\\nschemes:\\n  - http\\nsecurityDefinitions:\\n  basicAuth:\\n    type: basic\\nsecurity:\\n  - basicAuth: []\\npaths:\\n  /:\\n    get:\\n      description: \' PersonsREST general information \'\\n      summary: \' Server Info \'\\n      operationId: GetInfo\\n      x-ISC_CORS: true\\n      x-ISC_ServiceMethod: GetInfo\\n      responses:\\n        \'200\':\\n          description: (Expected Result)\\n          schema:\\n            type: object\\n            properties:\\n              version:\\n                type: string\\n        default:\\n          description: (Unexpected Error)\\n  /persons/all:\\n    get:\\n      description: \' Retreive all the records of Sample.Person \'\\n      summary: \' Get all records of Person class \'\\n      operationId: GetAllPersons\\n      x-ISC_ServiceMethod: GetAllPersons\\n      responses:\\n        \'200\':\\n          description: (Expected Result)\\n          schema:\\n            type: array\\n            items:\\n              $ref: \'#/definitions/Person\'\\n        default:\\n          description: (Unexpected Error)\\n  \'/persons/{id}\':\\n    get:\\n      description: \' Return one record fo Sample.Person \'\\n      summary: \' GET method to return JSON for a given person id\'\\n      operationId: GetPerson\\n      x-ISC_ServiceMethod: GetPerson\\n      parameters:\\n        - name: id\\n          in: path\\n          required: true\\n          type: string\\n      responses:\\n        \'200\':\\n          description: (Expected Result)\\n          schema:\\n            $ref: \'#/definitions/Person\'\\n        default:\\n          description: (Unexpected Error)\\n    put:\\n      description: \' Update a record in Sample.Person with id \'\\n      summary: \' Update a person with id\'\\n      operationId: UpdatePerson\\n      x-ISC_ServiceMethod: UpdatePerson\\n      parameters:\\n        - name: id\\n          in: path\\n          required: true\\n          type: string\\n        - name: payloadBody\\n          in: body\\n          description: Request body contents\\n          required: false\\n          schema:\\n            type: string\\n      responses:\\n        \'200\':\\n          description: (Expected Result)\\n        default:\\n          description: (Unexpected Error)\\n    delete:\\n      description: \' Delete a record with id in Sample.Person \'\\n      summary: \' Delete a person with id\'\\n      operationId: DeletePerson\\n      x-ISC_ServiceMethod: DeletePerson\\n      parameters:\\n        - name: id\\n          in: path\\n          required: true\\n          type: string\\n      responses:\\n        \'200\':\\n          description: (Expected Result)\\n        default:\\n          description: (Unexpected Error)\\n  /persons/:\\n    post:\\n      description: \' Creates a new Sample.Person record \'\\n      summary: \' Create a person\'\\n      operationId: CreatePerson\\n      x-ISC_ServiceMethod: CreatePerson\\n      parameters:\\n        - name: payloadBody\\n          in: body\\n          description: Request body contents\\n          required: false\\n          schema:\\n            type: string\\n      responses:\\n        \'200\':\\n          description: (Expected Result)\\n        default:\\n          description: (Unexpected Error)\\ndefinitions:\\n  Person:\\n    type: object\\n    properties:\\n      Name:\\n        type: string\\n      Title:\\n        type: string\\n      Company:\\n        type: string\\n      Phone:\\n        type: string\\n      DOB:\\n        type: string\\n        format: date-time\\n"}'

Ce qui est important ici, c'est cette partie :

x-headmatter:
  readable_by:
    - dev

Référez-vous à cette documentation : readable_by attribute

8.2.3. Essayez !

8.2.3.1. Inscrire un nouveau développeur

vidéo

8.2.3.2. Approuver ce développeur

vidéo

8.2.3.3. Ajouter un rôle pour ce développeur

vidéo


curl 'http://localhost:8001/default/developers/dev@dev.com' -X PATCH --compressed -H 'Content-Type: application/json;charset=utf-8' -H 'Cache-Control: no-cache' -H 'Origin: http://localhost:8002' -H 'DNT: 1' -H 'Connection: keep-alive' -H 'Referer: http://localhost:8002/default/portal/permissions/dev/update' -H 'Pragma: no-cache' --data-raw '{"roles":["dev"]}'

8.3. Ajouter Oauth2 pour le développeur

Dans cette partie, nous allons ajouter une authentification Oauth2 pour que les développeurs puissent utiliser notre API crud de manière sécurisée.

Ce flux permettra l'auto-enregistrement du développeur et lui donnera accès à l'API crud.

8.3.1. Tout d'abord, retirez l'authentification de base

Pour ce faire, nous allons remplacer notre authentification de base par une authentification bearToken.

Désactivez d'abord notre authentification/acl de base.

Portail IAM

foo

API Rest


# Désactiver le plugin ACL

curl 'http://localhost:8001/default/routes/afefe836-b9be-49a8-927a-1324a8597a9c/plugins/3f2e605e-9cb6-454a-83ec-d1b1929b1d30' -X PATCH --compressed -H 'Content-Type: application/json;charset=utf-8' -H 'Cache-Control: no-cache' -H 'Origin: http://localhost:8002' -H 'DNT: 1' -H 'Connection: keep-alive' -H 'Referer: http://localhost:8002/default/plugins/acl/3f2e605e-9cb6-454a-83ec-d1b1929b1d30/update' -H 'Pragma: no-cache' --data-raw '{"enabled":false,"name":"acl","route":{"id":"afefe836-b9be-49a8-927a-1324a8597a9c"},"config":{"hide_groups_header":false,"whitelist":["user","dev","crud"]}}'

8.3.2. Ensuite, ajoutez le plugin de demande d'inscription

Portail IAM API Rest

foo


# Créer un plugin d'enregistrement d'application

curl -i -X POST \
--url http://localhost:8001/services/crud/plugins \
--data 'name=application-registration' \
--data 'config.auth_header_name=authorization' \
--data 'config.auto_approve=true' \
--data 'config.display_name=auth' \
--data 'config.enable_client_credentials=true' 

8.3.3. Associez le service et la documentation

Portail IAM

foo

API Rest


curl 'http://localhost:8001/default/document_objects' --compressed -H 'Content-Type: application/json;charset=utf-8' -H 'Cache-Control: no-cache' -H 'Origin: http://localhost:8002' -H 'DNT: 1' -H 'Connection: keep-alive' -H 'Referer: http://localhost:8002/default/services/create-documentation' -H 'Pragma: no-cache' --data-raw '{"service":{"id":"7bcef2e6-117c-487a-aab2-c7e57a0bf61a"},"path":"specs/iam-training.yml"}'

8.3.3.1. Essayez !

À partir du portail des développeurs, connecté en tant que dev@dev.com, créez une nouvelle demande.

alt

Cela vous donnera client_id et client_secret.

Il peuvent être utilisé dans le portail développeur.

Inscrivez cette demande dans le service crud :

alt

Obtenez un jeton :


curl --insecure -X POST https://localhost:8443/persons/oauth2/token \
  --data "grant_type=client_credentials" \
  --data "client_id=2TXNvDqjeVMHydJbjv9t96lWTXOKAtU8" \
  --data "client_secret=V6Vma6AtIvl04UYssz6gAxPc92eCF4KR"

Utilisez le jeton :


curl --insecure -X GET https://localhost:8443/persons/all \
  --header "authorization: Bearer u5guWaYR3BjZ1KdwuBSC6C7udCYxj5vK"

9. Portail de gestion sécurisé

9.1. Créer un administrateur

Comme nous avons amorcé Kong sans mot de passe de démarrage.

Nous devons créer un administrateur avant d'appliquer RBAC.

Pour cela :

  • Allez dans Équipes
  • Invitez un administrateur
    • Définissez l'adresse e-mail
    • Définissez le nom d'utilisateur
      • Définissez le rôle sur super administrateur
    • Invitez
  • Allez dans Administrateur invité
  • Affichez
  • Créez un lien

alt

9.2. Activer l'authentification de base pour Kong Manager

Pour activer cette fonctionnalité, nous devons modifier le fichier docker-compose.

Ajoutez ceci au service iam, environnement

      KONG_ENFORCE_RBAC: 'on'
      KONG_ADMIN_GUI_AUTH: 'basic-auth'
      KONG_ADMIN_GUI_SESSION_CONF: '{"secret":"${IRIS_PASSWORD}","storage":"kong","cookie_secure":false}'

Redémarrez le conteneur


docker-compose down && docker-compose up -d

Allez au lien administrateur invité :

http://localhost:8002/register?email=test.test%40gmail.com&username=admin&token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MTYzMzYzNzEsImlkIjoiY2JiZGE5Y2UtODQ3NS00MmM2LTk4ZjItNDgwZTI4MjQ4NWNkIn0.sFeOc_5UPIr3MdlQrgyGvmvIjRFvSn3nQjo2ph8GrJA

9.3. Utiliser l'API Kong Admin avec RBAC

Comme RBAC est défini, nous ne pouvons plus utiliser l'api kong admin :


curl -s -X GET \
  --url http://localhost:8001/routes

Revoie cette erreur :

{"message":"Identifiants incorrects. Jeton ou identifiants utilisateurs requis"}

9.3.1. Créer un utilisateur administrateur avec un jeton

  • Allez dans Équipes
  • Utilisateurs RBAC
  • Ajouter un nouvel utilisateur

alt


curl -s -X GET \
  --url http://localhost:8001/routes \
  --header "Kong-Admin-Token: SYS"

10. Plug-ins

alt

Kong est livré avec des plugins de haute qualité.

Mais et si nous avions besoin de plugins qui ne soient pas intégrés ? Si nous voulons des plugins communautaires ?

Dans ce chapitre, nous allons parler des plugins communautaires et comment les importer.

Ensuite, nous verrons comment compiler notre propre plugin.

10.1. Importer un plugin communautaire

Pour cette partie, nous allons utiliser le plugin jwt-crafter.

Ce plugin ajoute la possibilité de générer un jeton JWT au sein même de Kong, éliminant ainsi le besoin d'un service en amont effectuant la génération du jeton.

Voici le plugin :

https://github.com/grongierisc/kong-plugin-jwt-crafter

Pour installer ce plugin, comme nous utilisons la version docker, nous devons compiler une nouvelle image qui intègre le plugin.

10.1.1. Compliez une nouvelle image Kong/IAM avec le plugin communautaire

  1. Créez un dossier nommé iam à la racine de ce git.
  2. Créez un dockerfile dans ce nouveau dossier
  3. Créez un dossier nommé plugins
    1. C'est ici que nous ajouterons tous nos plugins communautaires
  4. Mettez à jour le fichier docker-compose pour activer le nouveau plug-in

Dans le dossier des plugins, git clonez notre plugin communautaire.


git clone https://github.com/grongierisc/kong-plugin-jwt-crafter

Le dockerfile doit ressembler à ceci :

FROM intersystems/iam:1.5.0.9-4

USER root
COPY ./plugins /custom/plugins

RUN cd /custom/plugins/kong-plugin-jwt-crafter && luarocks make

USER kong

Que voyons-nous dans ce dockerfile ?

Pour installer simplement un plugin communautaire, nous devons nous rendre dans son dossier racine (où se trouve le rockspec) et appeler luarocks make. C'est tout. Vous avez installé le plugin.

Pour la partie docker-compose :

  1. Modifiez la balise iam iamge
    1. intersystems/iam:1.5.0.9-4 -> intersystems/iam-custom:1.5.0.9-4
  2. Ajoutez un contexte de compilation
    build: 
      context: iam
      dockerfile: dockerfile
  1. Activez le plugin dans les variables d'environnement
KONG_PLUGINS: 'bundled,jwt-crafter'

Maintenant, compilons notre nouvelle image iam :


docker-compose build iam

10.1.2. Essayez !


docker-compose up -d

Si vous allez dans plugin -> nouveau, en bas de la liste vous devriez voir le plugin jwt-crafter.

alt

10.1.2.1. Utilisez-le !

  1. Créez un nouveau service :
Portail IAM API Rest

foo


# Créer un service

curl -i -X POST \
--url http://localhost:8001/services/ \
--data 'name=crud-persons' \
--data 'url=http://iris:52773/crud/persons/'
  1. Créez une route
Portail IAM API Rest

foo


# Créer une route

curl -i -X POST \
--url http://localhost:8001/services/crud-persons/routes \
--data 'name=crud-route-jwt' \
--data 'paths=/crud/persons/*' \
--data 'strip_path=true'
  1. Réutilisez notre authentification automatique
Portail IAM API Rest

foo


# Créer un plugin
curl -i -X POST \
--url http://localhost:8001/services/crud-persons/plugins \
--data 'name=request-transformer' \
--data 'config.add.headers=Authorization:Basic U3VwZXJVc2VyOlNZUw==' \
--data 'config.replace.headers=Authorization:Basic U3VwZXJVc2VyOlNZUw=='

Maintenant tout est prêt. La véritable utilisation de jwt-crafter.

# Ajouter acl à la route
curl -i -X POST http://localhost:8001/routes/crud-route-jwt/plugins \
    --data "name=acl"  \
    --data "config.whitelist=test" \
    --data "config.hide_groups_header=false"

# Créer le service
curl -i -X POST \
  --url http://localhost:8001/services/ \
  --data 'name=jwt-login' \
  --data 'url=http://neverinvoked/'

# Créer une route
curl -i -X POST \
  --url http://localhost:8001/services/jwt-login/routes \
  --data 'name=jwt-login-route' \
  --data 'paths=/jwt/log-in'

# Activer l'authentification de base pour le service
curl -i -X POST http://localhost:8001/routes/jwt-login-route/plugins \
    --data "name=basic-auth"  \
    --data "config.hide_credentials=false"

# Activer l'authentification de base pour le service
curl -i -X POST http://localhost:8001/routes/jwt-login-route/plugins \
    --data "name=jwt-crafter"  \
    --data "config.expires_in=86400"

# Ajouter un consommateur
curl -i -X POST \
   --url http://localhost:8001/consumers/ \
   --data "username=test"

# Ajouter un groupe consommateur
curl -i -X POST \
   --url http://localhost:8001/consumers/test/acls \
   --data "group=test"

# Ajouter des identifiants consommateur
curl -i -X POST http://localhost:8001/consumers/test/basic-auth \
    --data "username=test" \
    --data "password=test"
curl -i -X POST http://localhost:8001/consumers/test/jwt \
    --data "key=test" \
    --data "algorithm=HS256"

# Plugins JWT
curl -i -X POST http://localhost:8001/routes/crud-route-jwt/plugins \
    --data "name=jwt" 

Essayez !

# test:test est en base64
curl -H 'Authorization: basic dGVzdDp0ZXN0' localhost:8000/jwt/log-in
curl --location --request GET 'http://localhost:8000/crud/persons/all' \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW0iOiJ0ZXN0Iiwic3ViIjoiODJiNjcwZDgtNmY2OC00NDE5LWJiMmMtMmYxZjMxNTViN2E2Iiwicm9sIjpbInRlc3QiXSwiZXhwIjoxNjE2MjUyMTIwLCJpc3MiOiJ0ZXN0In0.g2jFqe0hDPumy8_gG7J3nYsuZ8KUz9SgZOecdBDhfns'

10.2. Créer un nouveau plugin

Ce n'est pas l'endroit pour apprendre le lua.

Mais je vous donnerai quelques astuces comme la façon de redémarrer rapidement IAM pour tester notre nouveau développement.

10.2.1. Structure de fichiers

kong-plugin-helloworld
├── kong
│   └── plugins
│       └── helloworld
│           ├── handler.lua
│           └── schema.lua
└── kong-plugin-helloworld-0.1.0-1.rockspec

Par convention, les plugins kong doivent être préfixés par kong-plugin.

Dans notre exemple, le nom du plugin est helloworld.

Trois fichiers sont obligatoires :

  • handler.lua : le cœur de votre plugin. Il s'agit d'une interface à mettre en œuvre, dans laquelle chaque fonction sera exécutée au moment souhaité dans le cycle de vie d'une demande/connexion.
  • schema.lua : votre plugin doit probablement conserver une configuration saisie par l'utilisateur. Ce module contient le schéma de cette configuration et définit des règles sur celui-ci, afin que l'utilisateur ne puisse saisir que des valeurs de configuration valides.
  • *.rockspec : Rockspec : un fichier de spécification de paquetage Un script Lua déclaratif, avec des règles sur la façon de compiler et d'empaqueter rocks *.rockspec - un fichier Lua contenant quelques tableaux.

10.2.1.1. handler.lua

L'interface du plugin vous permet de remplacer l'une des méthodes suivantes dans votre fichier handler.lua pour mettre en œuvre une logique personnalisée à divers points d'entrée du cycle de vie de Kong :

Nom de la fonctionPhaseDescription
:init_worker()init_workerExécuté au démarrage de chaque processus worker Nginx.
:certificate()ssl_certificateExécuté pendant la phase de service du certificat SSL de la poignée de main SSL.
:rewrite()rewriteExécuté pour chaque demande à sa réception d'un client en tant que gestionnaire de la phase de réécriture. NOTE : dans cette phase, ni le Service ni le Consommateur n'ont été identifiés, donc ce gestionnaire ne sera exécuté que si le plugin a été configuré comme un plugin global !
:access()accessExécuté pour chaque demande d'un client et avant qu'elle ne soit transmise par proxy au service en amont.
:response()accessRemplace à la fois header_filter() et body_filter(). Exécuté après la réception de la réponse complète du service en amont, mais avant d'en envoyer une partie au client.
:header_filter()header_filterExécuté lorsque tous les octets d'en-tête de réponse ont été reçus du service en amont.
:body_filter()body_filterExécuté pour chaque fragment du corps de la réponse reçu du service en amont. Comme la réponse est renvoyée au client en continu, elle peut dépasser la taille du tampon et être envoyée par morceaux. cette méthode peut donc être appelée plusieurs fois si la réponse est importante. Consultez la documentation de lua-nginx-module pour plus de détails.
:log()journalExécuté lorsque le dernier octet de réponse a été envoyé au client.
10.2.1.1.1. Exemple
local BasePlugin = require "kong.plugins.base_plugin"

local HelloWorldHandler = BasePlugin:extend()

function HelloWorldHandler:new()
  HelloWorldHandler.super.new(self, "helloworld")
end

function HelloWorldHandler:access(conf)
  HelloWorldHandler.super.access(self)
  if conf.say_hello then
    ngx.log(ngx.ERR, "============ Hello World! ============")
    ngx.header["Hello-World"] = "Hello World!!!"
  else
    ngx.log(ngx.ERR, "============ Bye World! ============")
    ngx.header["Hello-World"] = "Bye World!!!"
  end
end

return HelloWorldHandler

10.2.1.2. schema.lua

Simplement le fichier de configuration vu dans le portail.

return {
    no_consumer = true,
    fields = {
      say_hello = { type = "boolean", default = true },
      say_hello_body = { type = "boolean", default = true }
    }
  }

10.2.1.3. *.rockspec

package = "kong-plugin-helloworld" -- hint : renommer, doit correspondre à l'info dans le nom de fichier de ce rockspec !
                                  -- comme convention ; tenez-vous en au préfixe : « kong-plugin- »
version = "0.1.0-1" -- indice : n'oubliez pas, il doit correspondre à l'info dans le nom de fichier de ce rockspec !
-- La version « 0.1.0 » est la version du code source, le « 1 » suivant est la version de ce rockspec.
-- à chaque fois que la version de la source change, le rockspec doit être réinitialisé à 1. La version rockspec est seulement
-- mise à jour (incrémentée) lorsque ce fichier change, mais la source reste la même.

-- TODO : C'est le nom à définir dans le paramètre « plugins » de la configuration Kong.
-- Ici, nous l'extrayons du nom du paquet.
local pluginName = package:match("^kong%-plugin%-(.+)$")  -- "myPlugin"

supported_platforms = {"linux", "macosx"}
source = {
  url = "https://github.com/grongierisc/iam-training",
  branch = "master",
--  tag = "0.1.0"
-- hint: "tag" could be used to match tag in the repository
}

description = {
  summary = "Ceci est une démo pour le plugin Kong",
  homepage = "https://github.com/grongierisc/iam-training",
  license = "Apache 2.0"
}

dependencies = {
   "lua >= 5.1"
   -- other dependencies should appear here
}

build = {
  type = "builtin",
  modules = {
    ["kong.plugins."..pluginName..".handler"] = "kong/plugins/"..pluginName.."/handler.lua",
    ["kong.plugins."..pluginName..".schema"] = "kong/plugins/"..pluginName.."/schema.lua",
  }
}

10.2.2. Compilez-le

Nous ferons la même chose qu'ici : 11.1.1. Compilez une nouvelle image Kong/IAM avec le plugin communautaire

Mais adapté à notre plugin :

Dockerfile :

FROM intersystems/iam:1.5.0.9-4

USER root
COPY ./plugins /custom/plugins

RUN cd /custom/plugins/kong-plugin-jwt-crafter && luarocks make
RUN cd /custom/plugins/kong-plugin-helloworld && luarocks make

#USER kong #Rester root, nous verrons pourquoi plus tard

Activez le plugin dans les variables d'environnement

KONG_PLUGINS: 'bundled,jwt-crafter,helloworld'

Maintenant, compilons notre nouvelle image iam :


docker-compose build iam

Puis docker-compose up et testez-le.

10.2.3. Astuces

Pour exécuter le conteneur IAM en « mode débogage », pour l'arrêter/le redémarrer facilement, modifier le dockerfile pour ajouter/supprimer le plugin et ainsi de suite.

Vous pouvez arrêter le service iam :


docker-compose stop iam

Et lancez-le en mode exécution avec un shell :


docker-compose run -p 8000:8000 -p 8001:8001 -p 8002:8002 iam sh

Dans le conteneur :


./docker-entrypoint.sh kong

Bonne programmation :)

11. CI / CD

alt

Nous sommes proches de la fin de cet article.

Pour finir, parlons de DevOps/CI/CD. L'objectif de ce chapitre est de vous donner quelques idées sur la manière d'implémenter/scripter ci/cd pour IAM/Kong.

Comme Kong est d'abord une API, l'idée est de scripter tous les appels rest et de jouer ensuite sur chaque environnement.

La façon la plus simple de scripter les appels Rest est avec postman et son meilleur ami newman (version en ligne de commande de postman).

11.1. Créer la collection Postman

Une chose pratique avec postman est sa capacité à exécuter un script avant et après un appel rest.

Nous utiliserons cette fonctionnalité dans la plupart des cas.

11.1.1. IAM est-il démarré ?

Notre premier script va vérifier si IAM est en place et fonctionne.

alt

var iam_url = pm.environment.get("iam_url");
var iam_config_port = pm.environment.get("iam_config_port");
var url = "http://" + iam_url + ":" + iam_config_port + "/";
SenReq(20);
async function SenReq(maxRequest) {
    var next_request = "end request";
    const result = await SendRequest(maxRequest);
    console.log("result:",result);
    if(result == -1)
    {
        console.error("IAM starting .... failed !!!!");
    }
}

function SendRequest(maxRequest) {
    return new Promise(resolve => {
        pm.sendRequest(url,
            function (err) {
                if (err) {
                    if (maxRequest > 1) {
                        setTimeout(function () {}, 5000);
                        console.warn("IAM not started...retry..next retry in 5 sec");
                        SendRequest(maxRequest - 1);
                    } else {
                        console.error("IAM starting .... failed");
                        resolve(-1);
                    }
                } else {
                    console.log("IAM starting .... ok");
                    resolve(1);
                }

            }
        );
    });
}

11.1.2. Supprimer les anciennes données


var iam_url=pm.environment.get("iam_url");
var iam_config_port=pm.environment.get("iam_config_port");

pm.sendRequest("http://"+iam_url+":"+iam_config_port+"/plugins", function (err, res) {
    if (err) {
        console.log("ERROR : ",err);
    } 
    else {

        var body_json=res.json();
        if(body_json.data)
        {
            for( i=0; i < body_json.data.length; i++)
            {
                // Example with a full fledged SDK Request
                route_id = body_json.data[i].id;
                const delete_route = {
                  url: "http://"+iam_url+":"+iam_config_port+"/plugins/" + route_id,
                  method: 'DELETE',
                };
                pm.sendRequest(delete_route, function(err, res){
                    console.log(err ? err : res);
                });
            }
        }
    }
});

Faites de même pour les routes, les services et les consommateurs.

Cet ordre est important car vous ne pouvez pas supprimer les services avec des routes.

11.1.3. Créer un service/route

Les routes dépendent des services. Pour ce type de cas, nous pouvons utiliser la fonction Test de postman pour récupérer les données :

alt

Écran Script

foo


var id = pm.response.json().id;
var name = pm.response.json().name;
pm.globals.set("service_crud_id", id);
pm.globals.set("service_crud_name", name);

Ici, nous sauvegardons de la réponse l'ID et le nom des nouveaux services.

Ensuite, nous pouvons l'utiliser dans la prochaine création de route :

Écran Script

foo


service_crud_name = pm.globals.get("service_crud_name");

Ici, nous récupérons la variable globale « service_crud_name ».

Ensuite, utilisez-le dans l'appel réel.

Écran Script

foo


{
    "paths": [
        "/persons/*"
    ],
    "protocols": [
        "http"
    ],
    "name": "crud-persons",
    "strip_path": false,
    "service": {
        "name": "{{service_crud_name}}"
        }
}

11.1.3.1. Astuces

  • le contenu peut être soit au format json, soit au format form-data
    • form-data :

alt

  • json :

alt

Une façon simple d'obtenir le format json, allez sur le portail du gestionnaire, affichez, copiez le json :

alt

11.2. Exécutez-le avec newman


docker run  --rm -v "`pwd`/ci/":"/etc/newman" \
 --network="iam-training_default" \
 -t postman/newman run "DevOps_IAM.postman_collection.json" \
 --environment="DevOps_IAM.postman_environment.json"
2
0 278