1. Təcrübədə Auth Server nədir və niyə Keycloak seçirik
Qısa xatırlatma ilə başlayaq: Auth Server (IdP) — bu, aşağıdakıları edən xidmətdir:
- istifadəçiyə login/qeydiyyat və consent ekranını göstərir;
- OAuth/OIDC‑tokenlər verir (access_token, id_token, refresh_token);
- discovery sənədini və JWKS açarlarını dərc edir ki, resurs serverləri bu tokenləri yoxlaya bilsin.
Bizim stack-də:
- ChatGPT / MCP Jam OAuth‑müştəri kimi çıxış edir (public client);
- sizin MCP‑serveriniz — Resource Server kimi;
- Keycloak — Auth Server kimi.
Niyə Keycloak həm kurs, həm də real həyatda rahatdır:
- o, open source‑dur, lokal/Docker-da asanlıqla qaldırmaq olar;
- onun obyekt modeli kifayət qədər şəffafdır: realm, clients, users, roles;
- mahiyyətcə, Keycloak-da öyrəndiyiniz istənilən konfiqurasiya demək olar ki, 1:1 Auth0/Okta/Cognito-a köçürülür: orada da eyni ideyalar — client, scopes, redirect URIs, PKCE.
Vacib fikir: biz bütün layihə üçün Keycloak yox, məhz bizim ChatGPT App üçün ayrıca Realm sazlayırıq. Bu, məhz MCP‑müştərilərin autentifikasiyası üçün bir “qum qutusu”dur.
Qısası, mühazirənin sonunda sizdə olacaq:
- ChatGPT tətbiqi üçün Keycloak-da öz realm‑ınız;
- Authorization Code + PKCE ilə sazlanmış public‑client;
- minimal scopes və claims dəsti;
- bu tokenin sizin Node‑MCP‑serverinizdə necə “yaşadığını” anlama.
2. MCP prizmasından Keycloak-ın əsas obyektləri
Sonradan admin paneldə it-bat olmamaq üçün obyektləri rəflərə düzək.
Realm: sazlamalar və istifadəçilər üçün məkan
Keycloak-da Realm — öz istifadəçiləri, müştəriləri və siyasətləri olan izolə olunmuş məkandır. Rahat analoq — biznes mərkəzində icarəyə götürülmüş ofis: hər kəsin öz otağı, öz əməkdaş siyahısı və giriş qaydaları var.
Kurs və ilk real App-ınız üçün ayrıca realm yaratmaq mənalıdır, məsələn, giftgenius-mcp və ya mcp-course. Bu, aşağıdakıları təmin edir:
- master realm-ına toxunmamaq, yəni admin paneli təsadüfən pozmamaq;
- realm-i ixrac/idxal etməklə fərqli mühitlər (dev / staging / prod) arasında sazlamaları və istifadəçiləri təkrar istifadə etmək.
Client: tətbiq haqqında qeyd (ChatGPT / MCP Jam)
Keycloak-da Client — “istifadəçi” deyil, token almaq üçün Auth Server-ə müraciət edən tətbiqdir. Bizim halda bu, sizin Next.js backend deyil, məhz MCP‑müştəridir: ChatGPT, MCP Jam, bəlkə də ayrıca vidcetiniz, əgər UI-də əl ilə OAuth‑flow edirsinizsə.
Müştərinin əsas sahələri:
- client_id — sətir şəklində identifikator;
- növ (public / confidential / bearer-only);
- aktiv edilən OAuth axınları (Standard Flow, Client Credentials və s.);
- icazəli redirect URI siyahısı;
- scopes siyahısı və protocol mappers (token-dəki claims).
ChatGPT/MCP Jam üçün bizə public client lazımdır, çünki:
- ChatGPT müştəri kimi client_secret-i təhlükəsiz saxlaya bilmir;
- MCP Jam da desktop/brauzer aləti kimi etibarsız mühitdədir.
User: real insan
User — artıq “canlı” istifadəçidir: onun username, parol, email, atributlar, qruplar, rollar var. Kim Keycloak vasitəsilə login edirsə, məhz onun sub və digər məlumatları token-ə düşür, siz isə sonra MCP‑serverdə bu tokeni yoxlayır və öz accountId / tenantId modellərinizlə map edirsiniz.
Bizim demo səviyyəsində kifayətdir:
- bir-iki test istifadəçisi (məsələn, alice@example.com, bob@example.com);
- istəyə görə tenant və ya plan kimi bir-iki atribut — əgər token-dəki claims-in tools davranışına necə təsir etdiyini göstərmək istəyirik.
3. Müştəri növünün seçimi: public, PKCE və niyə secretsiz
İndi mahiyyətə keçək: ChatGPT/MCP üçün Keycloak-da müştərini necə sazlamaq.
Public vs Confidential: niyə client_secret deyil
Klassik veb tətbiqində siz backend yaradırsınız, ora client_secret qoyursunuz və məhz server IdP-yə tokenlər üçün gedir. Bu, confidential client-dir: o, sirri saxlaya bilir.
ChatGPT dünyasında hər şey əksinədir:
- OAuth‑müştəri məhz ChatGPT platforması və ya MCP Jam kimi utilitdir;
- siz onun koduna və mühitinə nəzarət etmirsiniz;
- ChatGPT-yə verdiyiniz istənilən client_secret dərhal komprometləşmiş hesab olunmalıdır.
Ona görə də ChatGPT/Jam public clients kimi (yəni client_secret olmadan) işləyir və bunu PKCE — Proof Key for Code Exchange ilə kompensasiya edir.
PKCE nə edir — sadə dillə
PKCE — sessiya üçün bir dəfəlik “sir”dir. Məqsədi odur ki, authorization code-u sadəcə ələ keçirib başqa yerdən token-ə dəyişmək mümkün olmasın. Sxem belədir:
- Müştəri təsadüfi bir sətir code_verifier generasiya edir.
- Onu (adətən SHA-256 ilə) hash edir və code_challenge alır.
- /authorize-a redirect zamanı code_challenge və code_challenge_method=S256 göndərir.
- Login-dən sonra istifadəçi code ilə redirect URI-yə qayıdır.
- Müştəri POST /token edir, code və orijinal code_verifier göndərir.
- Keycloak verifier-i hash edir, challenge ilə müqayisə edir və hər şey qaydasındadırsa, token verir.
Bizim üçün vacib olan: bunların hamısını bizim yerimizə ChatGPT/MCP Jam edir. Biz sadəcə Keycloak-da müştəri üçün Authorization Code + PKCE (S256) dəstəyini aktiv etməli və client_secret tələb etməməliyik.
4. MCP ssenarisi üçün Keycloak-ın addım-addım sazlanması
Beləliklə, qərar verdik: ChatGPT/MCP Jam üçün bizə public client Authorization Code Flow və PKCE (S256) ilə, client_secret olmadan lazımdır. İndi isə bu konfiqurasiyanın Keycloak sazlamalarında necə göründüyünə baxaq.
Tutaq ki, sizdə artıq işlək Keycloak var (Docker konteyneri, lokal quraşdırma — fərqi yoxdur). Hazırda bizi düymələrin harda olduğundan çox sazlamaların məntiqi maraqlandırır.
Tətbiq üçün yeni realm yaradırıq
giftgenius-mcp adlı realm yaradaq: bu, aşağıdakılar üçün ayrıca sahə olacaq:
- məhz ChatGPT tətbiqi üçün istifadəçilər;
- ChatGPT/MCP Jam-ın OAuth-dan keçəcəyi müştərilər;
- öz parol və token siyasətləri.
Praktik məsləhət: admin panelə əməkdaşları autorizə etdiyiniz realm-i ChatGPT müştəriləri üçün realm ilə qarışdırmayın. Bu, həm daha təhlükəsiz, həm də məntiqcə daha sadədir.
Test istifadəçisi əlavə edirik
Məsələn, alice adlı istifadəçi yaradırıq:
- username: alice;
- email: alice@example.com;
- şifrə təyin edirik (sadəlik üçün — mürəkkəb siyasətlər olmadan);
- istəyə görə tenantId=demo-tenant atributu və ya ROLE_PREMIUM rolu əlavə edirik.
Sonradan MCP‑serverdə token-i decode edib sub, email, tenantId götürə və onları öz istifadəçi modelinizlə əlaqələndirə biləcəksiniz.
MCP Jam / ChatGPT üçün public client yaradırıq
İndi ən maraqlısı — Client.
Konseptual səviyyədə parametrlər belə olmalıdır:
- Client ID: giftgenius-mcp-client (ad sizin zövqünüzə görə);
- Növ: public / Client Authentication off;
- Standard Flow (Authorization Code) aktivdir;
- S256 metodu ilə PKCE aktivdir;
- redirect URI-lər sazlanıb;
- lazımi scopes sazlanıb (openid + sizin custom, məsələn, mcp:tools).
Standard Flow və PKCE-ni aktivləşdiririk
Məntiq səviyyəsində:
- Authorization Code Flow-u aktiv edirik (tez-tez “Standard Flow Enabled” adlanır);
- PKCE bölməsində pkceRequired=true və çox vaxt açıq şəkildə code_challenge_method=S256 göstəririk.
Niyə S256: müasir OAuth 2.1 sənədlərində və OpenAI/Model Context Protocol tövsiyələrində məhz S256 təhlükəsiz metod kimi dəstəklənir, plain‑PKCE təhlükəsiz sayılmır.
Redirect URI — ən kövrək nöqtə
Redirect URI müştərinin istifadə edəcəyi dəyərlə hərfən üst-üstə düşməlidir. Əks halda avtorizasiya mərhələsində invalid_redirect_uri xətası alacağıq.
Kursumuzda iki tipik müştəri var:
- MCP Jam/Inspector debug üçün. Onlar adətən http://localhost:PORT/... üzərində işləyir. Lokal ssenari üçün belə redirect-ə icazə vermək məntiqlidir:
- http://localhost:5173/* və ya Jam-in istifadə etdiyi konkret yol.
- ChatGPT / Apps SDK prod mühitində. Burada redirect URI-nı platformanın özü müəyyənləşdirir. Real inteqrasiyada siz OpenAI-nin aktual sənədlərinə baxacaq və ChatGPT-nin callback kimi istifadə edəcəyi URL-i qeyd edəcəksiniz.
Mühazirə çərçivəsində anlama vacibdir: ChatGPT istənilən redirect-i götürə bilməz, o, Auth Server-də yazılandan tam olaraq eyni olmalıdır. Buna görə:
- heç vaxt * və “istənilən URL keçərli olsun” yazmayın;
- lokal inkişaf üçün localhost çərçivəsində wildcard-lar qəbul edilə bilər, amma production üçün yox.
Scopes: minimum, amma kifayət
Scopes — müştərinin istədiyi hüquqların kiçik siyahısıdır.
Bizim MCP ssenarisi üçün çox vaxt gərək olur:
- openid — OpenID Connect-i aktiv etmək və sub sahəsi (bəzən email) olan id_token almaq üçün;
- custom scope, məsələn, mcp:tools, hansı ki “MCP alətlərinə giriş icazəlidir” mənasını daşıyır.
Keycloak-da bunu Client Scopes vasitəsilə etmək olar:
- openid-i saxlayın;
- lazım deyilsə, defolt olaraq artıq profile və email kimi scopeları söndürün;
- yeni mcp:tools scope-u əlavə edin və sonra Resource Server-də alətlərə girişi bununla məhdudlaşdırın.
Bu iki səbəbdən vacibdir:
- openid olmadan siz id_token və bəzi standart OIDC sahələrini almayacaqsınız.
- Ayrı custom scope olmadan MCP‑server tərəfdə dəqiq demək çətin olacaq: “bu token mənim alətlərimi çağırmaq üçün istifadə oluna bilər”.
5. Tokenlərin sazlanması: ömür, imza və claims
İndi Keycloak-ın hansı tokenləri verəcəyinə və onları MCP ssenarisi üçün necə sazlamağa baxaq.
Access token-in ömrü
Keycloak-da realm sazlamalarında Tokens bölməsi var, burada siz müəyyən edə bilərsiniz:
- Access Token Lifespan;
- Refresh Token Lifespan və digər taymoutlar.
ChatGPT App üçün qısaömürlü access tokenlər vacibdir:
- bir neçə dəqiqə və ya saat — normal dəyərdir;
- token köhnələrsə, MCP‑server 401 qaytarır, ChatGPT OAuth‑flow-u yenidən işə salır, istifadəçi lazım gələrsə bir daha login edir.
Ideya OpenAI-nin Apps SDK sənədlərindəki kimidir: qısa TTL + tokenlərin yenilənməsi və IdP tərəfində tokeni ləğv etməklə istifadəçini kifayət qədər tez “logout” etmək imkanı.
Refresh tokenlər ChatGPT müştərisi üçün, adətən, ya o qədər də kritik deyil, ya da qısa müddətə verilir ki, əbədi sessiyalar saxlanmasın.
Token-də görmək istədiyimiz claims
Minimum lazım olanlar:
- sub — Keycloak-da istifadəçinin unikal identifikatoru;
- iss — tokeni kim verib (issuer);
- aud — token hansı resurs üçündür (sonra MCP‑serverdə istifadə olunur);
- exp — bitmə vaxtı;
- scope — scopes siyahısı.
Əlavə olaraq tez-tez faydalıdır:
- email — istifadəçinin ünvanını görmək istəyirsinizsə;
- tenantId və ya oxşar claim — çoxtenantlı ssenarilər üçün;
- roles — əlavə avtorizasiya üçün.
Keycloak-da bu, Protocol Mappers vasitəsilə sazlanır:
- email, preferred_username və s. üçün standart mappers;
- istifadəçi atributları üçün custom mapper-lər (user.attribute → claim.name).
Nümunə: token-ə email-i claim kimi əlavə edən mapper, burada user.attribute=email, claim.name=email.
MCP‑server tərəfdə bu claims-ləri parse edilmiş JWT-dən götürüb:
- sub-u sizin accountId ilə əlaqələndirə bilərsiniz;
- tenantId-dən yalnız həmin tenant-a aid məlumatları seçmək üçün istifadə edə bilərsiniz;
- roles-dan daha “incə” hüquq bölgüsü üçün istifadə edə bilərsiniz.
Token imzası və JWKS
Keycloak, adətən, access/id tokenləri asimmetrik alqoritmlə (çox vaxt RS256) imzalayır və OpenID Discovery sənədindəki JWKS endpoint vasitəsilə açıq açarları dərc edir.
Bu, bizim üçün ona görə vacibdir ki, MCP‑server bacaracaq:
- token-dən issuer-i götürmək;
- /.well-known/openid-configuration vasitəsilə JWKS endpoint tapmaq;
- açıq açarı əldə edib tokenin imzasını lokalda yoxlamaq.
Bu hissəni “Mühafizə olunan resurs kimi MCP‑server” mühazirəsində daha detallı baxacağıq, amma artıq indi Keycloak-ın bu metadataları niyə verdiyini başa düşmək faydalıdır.
6. Dynamic Client Registration (DCR): nə zaman ümumiyyətlə lazımdır
Bu bölmə daha çox irəliləmiş mövzudur. İndiyə qədər müştərini admin paneldə “əl ilə” sazladıq və App-ı işə salmaq üçün bu, kifayətlə artıqlamadır. Amma OAuth protokolu müştərilərə ayrıca endpoint vasitəsilə dinamik qeydiyyatdan keçməyə imkan verir.
ChatGPT və MCP kontekstində OpenAI birbaşa yazır ki, platforma Dynamic Client Registration istifadə edə bilər. Yəni ChatGPT discovery sənədindəki registration_endpoint vasitəsilə Auth Server-də özünü “uçuş zamanı” qeydiyyatdan keçirir.
Keycloak səviyyəsində bu belə görünür:
- realm səviyyəsində DCR aktivləşdirilir;
- siz siyasət qurursunuz: kim yeni müştərilər qeydiyyatdan keçirə bilər və hansı grant types/scopes ilə.
Authorization Code + PKCE və openid mcp:tools scope-u ilə public client üçün JSON nümunəsi təxminən belə ola bilər:
{
"clientName": "My ChatGPT App",
"redirectUris": ["https://jam.proxy.mcpapps.com/callback"],
"grantTypes": ["authorization_code"],
"responseTypes": ["code"],
"scope": "openid mcp:tools",
"tokenEndpointAuthMethod": "none"
}
Burada tokenEndpointAuthMethod: "none" məhz client_secret olmadan public client deməkdir.
Kurs üçün sadəcə bunu bilmək kifayətdir ki:
- DCR, müştərilər çox olduqda və ya qısaömürlü olduqda faydalıdır;
- ChatGPT potensial olaraq sizin IdP-də özü qeydiyyatdan keçə bilər;
- amma ilk mərhələlərdə UI vasitəsilə yaradılmış statik müştəri ilə kifayətlənmək olar.
7. Bunun bizim tədris tətbiqimizlə əlaqəsi nədir
Yadımıza salaq ki, bizdə (məsələn, GiftGenius) adlı tədris MCP‑serveri var və o bacarır:
- mümkün hədiyyələrin siyahısını vermək;
- istifadəçinin hansısa istək siyahılarını saxlamaq;
- sonralar — commerce hissəsinə getmək, sifarişləri rəsmiləşdirmək və s.
Hələ MCP‑server açıq olanda o, kim müraciət edir, bilmir:
- ChatGPT-dən gələn sorğu məntiqli olaraq “Alice-dən” və ya “Bob-dan” ola bilər, amma MCP‑server bunu ayırd etmir;
- siz şəxsi hədiyyə tarixçəsini göstərə bilmirsiniz;
- lazımi hesabdan pulu inamla çıxara bilmirsiniz.
Keycloak-ı Auth Server kimi sazladıqdan sonra vəziyyət dəyişir:
- ChatGPT sizin MCP resursunun .well-known-una görə anlayır ki, o, qorunur və token tələb edir.
- ChatGPT istifadəçini Authorization Code + PKCE flow ilə Keycloak-a yönləndirir.
- İstifadəçi login edir (bizim alice).
- ChatGPT sub, email, mcp:tools və digər claims olan access token alır.
- ChatGPT artıq Authorization: Bearer <token> ilə GiftGenius alətini çağırır.
- MCP‑server tokeni yoxlayarkən anlayır: “Hə, bu Alice-dir, sub=... və tenantId=demo-tenant” — və uyğun cavab verir.
Bu zəncir növbəti mühazirədə tamamlanır: orada MCP‑serveri “həqiqi” resource server kimi edəcəyik — metadata endpoint-i, token yoxlamasını və istifadəçi ilə bağlamağı reallaşdıracağıq.
8. Kiçik praktiki nümunələr (stack: TypeScript + Node)
Aşağıdakılar “yeganə doğru” yol deyil, tipik Node/TypeScript stack-də bunun necə görünə biləcəyinə dair referensdir. Əgər siz indi daha çox Keycloak-da klikləməyə fokuslanmısınızsa, bu bölməni gözucu oxuyub MCP‑serveri qoşanda geri dönə bilərsiniz.
Keycloak sazlaması əsasən UI-dən klikləmə ilə və ya onun Admin REST API-si vasitəsilə edilir, amma bunun ətrafında bir neçə kod parçasını göstərmək faydalıdır ki, MCP‑server tərəfdə bunlardan necə istifadə edəcəyiniz aydın olsun.
Tutaq ki, bizdə artıq rəsmi SDK əsasında Node.js‑MCP‑server (TypeScript) var.
Auth konfiqurasiyası (issuer və audience)
authConfig.ts adlı kiçik modul yaradaq:
// authConfig.ts
export const authConfig = {
issuer: 'https://auth.my-company.com/realms/giftgenius-mcp',
audience: 'https://mcp.my-company.com', // Sizin MCP serverinizin URL-i
requiredScopes: ['mcp:tools'], // token-də tələb etdiyimiz minimum
};
Burada issuer — Keycloak realm-ının URL-i, audience — resursun identifikatorudur (biz onu token və MCP sazlamasında da istifadə edəcəyik).
JWKS vasitəsilə JWT-nin əsas yoxlanması
Real həyatda yəqin ki, jsonwebtoken + jwks-rsa kimi kitabxanadan və ya MCP SDK-dakı hazır utilitlərdən istifadə edəcəksiniz. Ən sadə skelet belə görünə bilər:
// verifyToken.ts
import jwt from 'jsonwebtoken';
import jwksClient from 'jwks-rsa';
import { authConfig } from './authConfig';
const client = jwksClient({
jwksUri: `${authConfig.issuer}/protocol/openid-connect/certs`,
});
function getKey(header: any, callback: any) {
client.getSigningKey(header.kid, (err, key) => {
const signingKey = key?.getPublicKey();
callback(err, signingKey);
});
}
export function verifyAccessToken(token: string): Promise<any> {
return new Promise((resolve, reject) => {
jwt.verify(
token,
getKey,
{
audience: authConfig.audience,
issuer: authConfig.issuer,
},
(err, decoded) => (err ? reject(err) : resolve(decoded)),
);
});
}
Əlbəttə, xəta emalı və açarların keşlənməsi daha səliqəli olmalıdır, amma ideyanı görürsünüz: Keycloak JWKS açarlarını dərc edir, biz onları çəkir və imzanı yoxlayırıq.
Scope-un yoxlanması və identity-nin çıxarılması
MCP alətləri üçün middleware-də buna bənzər bir şey edə bilərsiniz:
// authMiddleware.ts
import { verifyAccessToken } from './verifyToken';
import { authConfig } from './authConfig';
export async function requireAuth(bearerToken: string) {
const token = bearerToken.replace(/^Bearer\s+/i, '');
const decoded: any = await verifyAccessToken(token);
const scopes = (decoded.scope as string).split(' ');
const hasScope = authConfig.requiredScopes.every(s => scopes.includes(s));
if (!hasScope) {
throw new Error('Insufficient scope');
}
return {
userId: decoded.sub,
email: decoded.email,
tenantId: decoded.tenantId,
};
}
Sonra artıq MCP alətlərinin handler-lərində userId və tenantId-dən istifadə edərək istifadəçinin lazımi hədiyyə siyahılarını yükləyəcəksiniz. Alətləri biz artıq əvvəlki modullarda reallaşdırmışdıq, indi sadəcə Keycloak-dan gələn tokenin backend üçün anlaşılan identity-yə necə çevrildiyini görmək vacibdir.
9. MCP Auth Server kimi Keycloak sazlanarkən tipik səhvlər
Səhv №1: client_secret ilə confidential client istifadə olunur.
Bəzən vərdişlə confidential növündə müştəri yaradılır və client_secret MCP/ChatGPT konfiqinə yazılmağa çalışılır. ChatGPT App ekosistemində bu, işləməməlidir və təhlükəsiz də deyil: ChatGPT — public client-dir, o, sirri saxlaya bilməz. Düzgün yol — public client + PKCE.
Səhv №2: Defolt olaraq həddən artıq geniş scopes.
profile, email və başqa standart scopes-ları aktiv saxlayıb belə tokenləri hər chata paylamaq yaxşı fikir deyil. Minimumu saxlayın: openid və konkret mcp:tools (və ya bir-iki tətbiqi scope) — ilk versiyalar üçün kifayətdir. Bu, artıq məlumat sızması riskini azaldır və davranışı daha proqnozlaşdırılan edir.
Səhv №3: Yanlış redirect URI.
Klassika: Keycloak-da http://localhost:5173/callback yazılıb, amma MCP Jam http://localhost:5173/-a gedir. Və ya əksinə. Nəticədə — invalid_redirect_uri və çox yorucu debug. Həmişə Jam/ChatGPT sənədlərində redirect URI-nin dəqiq dəyərini yoxlayın və onu hərfi-hərfinə yazın.
Səhv №4: PKCE aktiv deyil və ya yanlış metodla aktivdir.
Keycloak-ın bəzi versiyalarında “PKCE required” ayrıca aktivləşdirilməli və S256 metodu göstərilməlidir. Bunu etməsəniz, PKCE gözləyən ChatGPT/Jam invalid_request xətası ala bilər və code_challenge-dan şikayət edər. Public‑müştərilər üçün PKCE sazlamalarını mütləq yoxlayın.
Səhv №5: Token-də yanlış və ya çatışmayan claims.
Bəzən token-də sub və ya email olmur, çünki uyğun scope və ya protocol mapper sazlanmayıb. Nəticədə MCP‑serverdə tokeni görürsünüz, amma onu real istifadəçi ilə map edə bilmirsiniz. Həll: lazım olan sahələrin (minimum sub, daha yaxşısı email/tenantId) access/id tokenlərə map olunduğuna əmin olun.
Səhv №6: Access tokenlər üçün həddən artıq uzun TTL.
Təhlükəsizlik baxımından access tokenləri bir gün/həftəlik vermək pis fikirdir. Token sızarsa, hücumçu MCP resursuna uzunmüddətli giriş əldə edəcək. Access tokenləri qısaömürlü edin (dəqiqələr və ya saatlar) və lazım gəldikdə təkrar avtorizasiyadan istifadə edin.
Səhv №7: Realm-lə bağlı çaşqınlıq və master-in istifadəsi.
Bəzən ilk edilən şey — müştəriləri və istifadəçiləri birbaşa master realm-da yaratmaqdır. Sonra ora daha bir-iki layihə də birləşdirilir — və nə haradadır, aydın olmur. Daha yaxşısı, konkret tətbiq/kurs üçün dərhal ayrıca realm açmaqdır. Bu, həm sizin, həm də DevOps-un işini asanlaşdıracaq.
GO TO FULL VERSION