Hacker DirectoryHacker Directory
Öğrenmeye devam et
ENHTML kaydet ↓

WEB / WEB-17.S02

GraphQL, streaming ve message authorization

Her operation, field ve event için güncel permission kararını connection’dan ayır.

CORE · RED · BLUE · ARTIFACT · PRACTICE

1. Core · Mekanizma

Hareket olmadan bütün senaryoları oku

Title izinli

  1. Read message hazır

    Consumer, note-A için notes.read action’ı ve title alanını seçerek GraphQL read mesajını hazırlar. API’nin Duru/tenant-A context’i bu örnekte önceden tanımlıdır; bu mesajın güncel izni henüz kararlaştırılmaz.

    Consumer
    notes.read message ready; title yok
    API / policy
    Policy bekliyor; title yok
    Public note store
    note-A sabit; read yok
  2. Message alındı

    API tamamlanmış message arrival’ı kaydeder; connection kabulü field veya zaman gate’ini çözmez.

    Consumer
    notes.read message ready; title yok
    API / policy
    notes.read geldi; current gate pending
    Public note store
    note-A sabit; read yok
  3. Current gate allow

    Object, field, cost ve current context koşulları ayrı kabul edildi; store read artık hazırlanabilir.

    Consumer
    notes.read message ready; title yok
    API / policy
    Object/field/current allow; store read ready
    Public note store
    note-A sabit; read yok
  4. Read store’a ulaştı

    Store approved read’in tamamlanmış arrival’ını görür; title projection henüz yerel olarak okunmamıştır.

    Consumer
    notes.read message ready; title yok
    API / policy
    Object/field/current allow; store read ready
    Public note store
    Approved note-A read received; body pending
  5. Title projection

    Store yerel read-only işlemle Tea & Bread başlığını hazırlar; nesne üzerinde mutation yoktur.

    Consumer
    notes.read message ready; title yok
    API / policy
    Object/field/current allow; store read ready
    Public note store
    Tea & Bread title body ready; mutation=false
  6. Title API’ye geldi

    Title body store’dan API’ye ulaştı; API kendi response projection’ını bir sonraki yerel adımda seçer.

    Consumer
    notes.read message ready; title yok
    API / policy
    Title received; API projection pending
    Public note store
    Tea & Bread title body ready; mutation=false
  7. Response hazır

    Seçilen GraphQL projection title’ı içerir; bu fixture actual GraphQL parser veya HTTP status testi değildir.

    Consumer
    notes.read message ready; title yok
    API / policy
    GraphQL title response ready; no mutation
    Public note store
    Tea & Bread title body ready; mutation=false
  8. Title teslim edildi

    Consumer’a tamamlanmış response arrival’ında title teslim edilir; sadece izinli read projection’ı taşınır.

    Consumer
    Received title=Tea & Bread; mutation=false
    API / policy
    GraphQL title response ready; no mutation
    Public note store
    Tea & Bread title body ready; mutation=false

Field reddi

  1. Read message hazır

    Consumer, note-A için notes.read action’ı ve title alanını seçerek GraphQL read mesajını hazırlar. API’nin Duru/tenant-A context’i bu örnekte önceden tanımlıdır; bu mesajın güncel izni henüz kararlaştırılmaz.

    Consumer
    notes.read message ready; title yok
    API / policy
    Policy bekliyor; title yok
    Public note store
    note-A sabit; read yok
  2. Message alındı

    API tamamlanmış message arrival’ı kaydeder; connection kabulü field veya zaman gate’ini çözmez.

    Consumer
    notes.read message ready; title yok
    API / policy
    notes.read geldi; current gate pending
    Public note store
    note-A sabit; read yok
  3. Current context

    API object ve operation context’ini yerel olarak değerlendirir; store’a henüz hiçbir read çıkmaz.

    Consumer
    notes.read message ready; title yok
    API / policy
    Object/action known; field/time gate pending
    Public note store
    note-A sabit; read yok
  4. Permission reddi

    Object, current context ve cost koşulları geçer, fakat fieldAllowed=false’tur. Nullable title için korunan değer okunmaz; store’a hiçbir read çıkmadan title=null ve error path note/title sonucu hazırlanabilir.

    Consumer
    notes.read message ready; title yok
    API / policy
    Nullable title field denied; value=null
    Public note store
    note-A sabit; read yok
  5. Denial response

    API, data.note.title=null ve errors içinde path=[note,title] içeren GraphQL envelope’ını hazırlar. expectedBody=null korunan title projection’ının yokluğudur; envelope yokluğu veya belirli HTTP status demek değildir.

    Consumer
    notes.read message ready; title yok
    API / policy
    Denial response ready; protected title absent
    Public note store
    note-A sabit; read yok
  6. Denial alındı

    Consumer denial response arrival’ını görür; body içindeki diagnostic korunan title içermez.

    Consumer
    GraphQL null title + errors alındı
    API / policy
    Denial response ready; protected title absent
    Public note store
    note-A sabit; read yok
  7. Result yorumlandı

    Consumer yerel olarak sonucunu yorumlar; schema veya açık channel permission yerine sayılmaz.

    Consumer
    Title değeri yok; HTTP status ayrı
    API / policy
    Denial response ready; protected title absent
    Public note store
    note-A sabit; read yok

Message expired

  1. Read message hazır

    Consumer, note-A için notes.read action’ı ve title alanını seçerek WebSocket read mesajını hazırlar. API’nin Duru/tenant-A context’i bu örnekte önceden tanımlıdır; bu mesajın güncel izni henüz kararlaştırılmaz.

    Consumer
    notes.read message ready; title yok
    API / policy
    Policy bekliyor; title yok
    Public note store
    note-A sabit; read yok
  2. Message alındı

    API tamamlanmış message arrival’ı kaydeder; connection kabulü field veya zaman gate’ini çözmez.

    Consumer
    notes.read message ready; title yok
    API / policy
    notes.read geldi; current gate pending
    Public note store
    note-A sabit; read yok
  3. Current context

    API object ve operation context’ini yerel olarak değerlendirir; store’a henüz hiçbir read çıkmaz.

    Consumer
    notes.read message ready; title yok
    API / policy
    Object/action known; field/time gate pending
    Public note store
    note-A sabit; read yok
  4. Permission reddi

    WebSocket daha önce kabul edilmiştir, fakat now=120 ile validUntil=120 sınırında current=false olur. Bu uygulamada equality geçersizdir; yeni message reddedilir, store read ve korunan title hazırlığı yapılmaz.

    Consumer
    notes.read message ready; title yok
    API / policy
    now=validUntil; message permission expired
    Public note store
    note-A sabit; read yok
  5. Denial response

    API, süresi dolan message için güvenli denial response’unu hazırlar; title içermez. Bu dal WebSocket message kararıdır, GraphQL null+errors envelope’ı veya connection close sonucu değildir.

    Consumer
    notes.read message ready; title yok
    API / policy
    Denial response ready; protected title absent
    Public note store
    note-A sabit; read yok
  6. Denial alındı

    Consumer denial response arrival’ını görür; body içindeki diagnostic korunan title içermez.

    Consumer
    Message denial alındı; title yok
    API / policy
    Denial response ready; protected title absent
    Public note store
    note-A sabit; read yok
  7. Result yorumlandı

    Consumer yerel olarak sonucunu yorumlar; schema veya açık channel permission yerine sayılmaz.

    Consumer
    Yeni title yok; eski data geri çekilmedi
    API / policy
    Denial response ready; protected title absent
    Public note store
    note-A sabit; read yok

Event tutuldu

  1. Subscription context

    Önceden kabul edilmiş stream vardır; bu başlangıç yeni event için permission iddiası değildir.

    Consumer
    Subscription önce kabul edildi; yeni title yok
    API / policy
    Önceki admission var; güncel izin bekliyor
    Public note store
    note-A sabit; read yok
  2. Event adaylığı

    Server yerel olarak yeni note event’ini değerlendirir; consumer’a henüz hiçbir event teslim edilmez.

    Consumer
    Subscription önce kabul edildi; yeni title yok
    API / policy
    Yeni event candidate; projection yok
    Public note store
    note-A sabit; read yok
  3. Current policy deny

    note-A için yeni SSE event’inde subscriptionAllowed=false verilmiştir. Önceki admission, event ID veya cursor bu ret koşulunu değiştirmez; title projection’ı hazırlanmaz.

    Consumer
    Subscription önce kabul edildi; yeni title yok
    API / policy
    Revoked; protected title body absent
    Public note store
    note-A sabit; read yok
  4. Delivery tutuldu

    Yeni event server’da tutulur; client close/reconnect gözlemi veya önceki verinin silinmesi modellenmez.

    Consumer
    Subscription önce kabul edildi; yeni title yok
    API / policy
    Event delivery=0; mutation=false; title absent
    Public note store
    note-A sabit; read yok

ROLLER · STATE · VERİ AKIŞI

Resolver bir permission sınırıdır

GraphQL schema, hangi field ve type’ların ifade edilebildiğini söyler; Duru’nun belirli note üzerinde hangi property’yi okuyabileceğini söylemez. Parse ve validation tamamlandıktan sonra resolver, authenticated actor, object ilişkisi, action ve field policy’sini aynı context içinde değerlendirmelidir. Atlas Notları yalnız note-A başlığını okumayı modeller. title nullable olarak seçilmiştir: field reddedilirse değer null olur ve errors içinde ilgili response path bulunur; izinli kardeş field’lar ayrı değerlendirilebilir. Non-Null kullanılsaydı null, uygun nullable parent’a kadar yayılabilirdi. Bu seçim uygulamanın authorization error politikasını görünür kılar; GraphQL standardı belirli bir access-control kütüphanesi veya evrensel HTTP status zorunlu kılmaz. data ve errors birlikte bulunması, korunan title’ın döndüğü anlamına gelmez.

Cost, type ve permission ayrı sorulardır

Bir resolver izinli olsa bile liste büyüklüğü ve tekrar eden alt seçimler kaynak tüketimini değiştirebilir. Query cost bu nedenle ayrı bir admission kararıdır; depth tek başına tüm fan-out’u açıklamaz. Defterde kullanılan title=1 ve liste sınırı=10 uygulamanın seçtiği öğretim değerleridir, GraphQL’in sabit katsayıları değildir. Cost kabulü permission vermez; permission kabulü de sınırsız iş bütçesi vermez. Node ve relationship üzerinden ulaşılan aynı nesneye farklı yolların policy’yi atlamadan aynı kararı uygulaması gerekir. Cache veya batch loader kullanılıyorsa key ve sonuç projection’ı actor/tenant/field bağlamına uygun olmalıdır. Sahne query parser, HTTP binding, gerçek resolver veya cache çalıştırmaz; izinli title projection’ının hangi koşullardan sonra hazırlanabileceğini adım adım gösterir.

WebSocket connection’dan message’a

WebSocket handshake’in kabul edilmesi bir communication channel açar. Bu karar tüm gelecekteki message’lara ve object’lere otomatik permission vermez. Browser Origin kontrolü, beklenen web application’dan gelen açılış isteğini değerlendirmeye yarar; non-browser client için bağımsız identity kanıtı değildir. Cookie’nin gönderilip gönderilmemesi de cookie ve browser kurallarına bağlıdır. Message handler, tanımlı shape ve action’ı çözüp güncel actor/session durumunu ve object policy’sini yeniden kullanır. Defterin expired dalında channel daha önce kabul edilmiştir, fakat now=120 ve validUntil=120 iken yeni notes.read message’ı reddedilir. Bu uygulamada equality geçersiz sayılır; WebSocket protokolü kendi başına böyle bir session timer tanımlamaz. Store’a read teslim edilmez ve title body hazırlanmaz.

SSE subscription’ın ömrü

SSE normalde server’dan client’a event akıtır; EventSource bir iki yönlü command channel değildir. İlk subscription admission’ı kadar, gelecekteki her event’in recipient ve object kapsamı da önemlidir. event id ve reconnect cursor hangi noktadan devam edileceğini anlatır; actor identity veya yeni permission yaratmaz. Subscription revoked olduğunda yeni title event’i tutulur. Sahnenin bu dalı server’ın yerel gate kararında biter: client’ın close gözlemi, reconnect ve daha önce aldığı verinin geri çekilmesi simüle edilmez. Ağ kapandığında EventSource yeniden bağlanmayı deneyebilir; server yeni admission’ı güncel context ile değerlendirmelidir. retry süresi transport davranışına yardım eder, exactly-once business delivery veya tüm event’lerin kayıpsız tekrarını garanti etmez. Kaynak aktarımı ile policy kararı aynı state olarak sunulmaz.

gRPC ve SOAP’a kısa fakat doğru giriş

gRPC bir service method çağrısını typed input/output ile ifade eder; Protocol Buffers yaygın varsayılandır. Unary, server streaming, client streaming ve bidirectional streaming farklı message akışlarıdır. Tek RPC içindeki stream ordering, başka RPC’nin veya business action’ın permission’ı değildir. Channel credentials ile call credentials farklı kapsamlardır; uygulama yine method ve object için karar verir. SOAP 1.2 ise XML Envelope içinde isteğe bağlı Header ve zorunlu Body yapısını tanımlar. Header’ın hangi node’da işlendiği ve Body’nin ultimate recipient’a yönelmesi, içerideki notes.read işleminin izinli olduğunu kanıtlamaz. Security gibi özellikler ek binding/extension ve uygulama profilinde tanımlanır. Defter yalnız bu karşılaştırmanın typed ledger’ıdır: gerçek protobuf message, SOAP XML parser, WS-Security signature veya remote RPC çalıştırılmamıştır.

2. Red · Güven ve etki

Hareket olmadan bütün senaryoları oku

Field reddi

  1. Operation koşulları seçildi

    field-denied row’u GraphQL için connectionAccepted=true, objectAllowed=true ve fieldAllowed=false içerir. İzinli object, title property’sinin otomatik açılması değildir.

    Operation koşulları
    GraphQL field gate
    Current policy gate
    Policy pending
    Resource projection
    Title hazırlanmadı
  2. Bağımsız gate koşulu ayrıldı

    costAllowed=true ve subscriptionAllowed=true olsa da fieldAllowed=false kalır. Cost budget’ın geçmesi field permission sağlamaz.

    Operation koşulları
    Other gates=true
    Current policy gate
    Field=false
    Resource projection
    Resource delivery pending
  3. Operation policy reddi verildi

    expectedAllowed=false, expectedResourceDelivery=false ve expectedMutation=false’tur. Handler protected title projection’ını hazırlamaz.

    Operation koşulları
    Allowed=false
    Current policy gate
    Mutation=false
    Resource projection
    Protected body=null
  4. Response ile protected data ayrıldı

    Selected nullable title schema’da graphqlEnvelope data.note.title=null ve errors path note/title içerir. Protected body null olması bütün envelope’ın yokluğu değildir.

    Operation koşulları
    Permission deny known
    Current policy gate
    Null title + errors
    Resource projection
    Mutation=false
  5. Transport policy’ye dönüştürülmedi

    GraphQL HTTP status bu envelope’dan otomatik türetilmez. Typed selection, cost sınırı ve resource/property permission ayrı contract katmanlarıdır.

    Operation koşulları
    Channel ≠ operation grant
    Current policy gate
    Policy gate independent
    Resource projection
    No extra status claim
  6. Ret kapsamı resource kararında kaldı

    Bilinen sonuç title delivery ve mutation’ın olmamasıdır. Gerçek GraphQL engine veya HTTP adapter’ın çalıştığı değil, bu nullable policy ledger’ının anlamı gösterilir.

    Operation koşulları
    No resource delivery
    Current policy gate
    No mutation
    Resource projection
    Runtime adapter unobserved

Context expired

  1. Operation koşulları seçildi

    expired row’u WebSocket için connectionAccepted=true ve validUntil=120 içerir. Profile now=120 seçer; açık channel context lifetime’ını uzatmaz.

    Operation koşulları
    now=120; validUntil=120
    Current policy gate
    Policy pending
    Resource projection
    Title hazırlanmadı
  2. Bağımsız gate koşulu ayrıldı

    Object, field, subscription ve cost koşulları true’dur fakat current=false’tur. Diğer olumlu alanlar expired context’i current yapmaz.

    Operation koşulları
    Other gates=true
    Current policy gate
    Current=false
    Resource projection
    Resource delivery pending
  3. Operation policy reddi verildi

    expectedAllowed=false, expectedResourceDelivery=false ve expectedMutation=false’tur. Handler protected title projection’ını hazırlamaz.

    Operation koşulları
    Allowed=false
    Current policy gate
    Mutation=false
    Resource projection
    Protected body=null
  4. Response ile protected data ayrıldı

    Bu row yeni resource body teslim etmez. Önceden teslim edilmiş data’nın browser hafızasından silindiği veya connection’ın otomatik kapandığı sonucu eklenmez.

    Operation koşulları
    Permission deny known
    Current policy gate
    No new delivery
    Resource projection
    Mutation=false
  5. Transport policy’ye dönüştürülmedi

    WebSocket connection credentials, her yeni message’ın current actor/action/object koşullarını sağlamaz. Bu aynı ayrım streamed gRPC message için de application policy sorusudur.

    Operation koşulları
    Channel ≠ operation grant
    Current policy gate
    Policy gate independent
    Resource projection
    No extra status claim
  6. Ret kapsamı resource kararında kaldı

    Bilinen sonuç zaman sınırındaki yeni read’in reddidir. Gerçek stream backpressure, Origin/Cookie enforcement veya revocation dağıtımı ayrıca gözlem ister.

    Operation koşulları
    No resource delivery
    Current policy gate
    No mutation
    Resource projection
    Runtime adapter unobserved

VARSAYIM · SINIR · KONTROL

Açık channel’a fazla anlam yüklemek

İncelenecek varsayım “connection kabul edildi, artık bu actor’ın bütün message’ları izinli” cümlesidir. Bunun yanlış sonuca dönüşmesi için uygulamanın current session, operation ve object kararını channel başlangıcındaki boolean’a indirgemesi gerekir. Defterde connectionAccepted=true ile messageAllowed=false aynı anda doğrudur; zaman sınırı dolduğunda store’a hiçbir yeni read gitmez. SSE’de de kabul edilmiş subscription ile yeni event delivery’si farklıdır. Red perspektif, açık channel’ın kendi başına bir zafiyet olduğunu iddia etmez: handler’ın güncel permission kontrolünü nereye koyduğunu ve hangi verinin o kontrolden önce hazırlandığını sorar. Revocation’ın nasıl yayıldığı hakkında kanıt yoksa sonuç “revocation çalışıyor” veya “çalışmıyor” değildir; bu bağımlılık unknown olarak kaydedilir. Önceden teslim edilmiş title’ın hafızadan silindiği de varsayılmaz.

Schema başarısından business yetkisine sıçramak

İkinci varsayım, type validation ve makul query cost sağlandığında resolver’ın object ve field policy’sine gerek kalmadığıdır. Bu karışıklığın etkisi sadece mutation değildir; title projection’ı da izin gerektiren bir disclosure olabilir. Buradaki note halka açık bir öğretim nesnesi olsa bile handler’ın selected title gate’i açıkça modellenir. Field-denied dalında response skeleton ve errors gönderilebilir, fakat korunan title değeri yoktur; “body yok” ifadesi tüm GraphQL envelope’ın yokluğunu değil title projection’ının yokluğunu anlatır. Typed gRPC request veya iyi biçimli SOAP Envelope da aynı business kararı devralmaz. Red inceleme yöntemi sabit policy satırlarının conjunction’ını izlemektir: operation, object, field ve zaman koşullarından hangisinin kanıtlandığı ayrı tutulur. Query çalıştırma, endpoint keşfi veya permission atlama denemesi bu örneğin bir parçası değildir.

3. Blue · Güvenli geliştirme ve savunma

Hareket olmadan bütün senaryoları oku

Event gate kapalı

  1. SSE subscription row’u okundu

    revoked row’unda connectionAccepted=true ve current=true’dur. subscriptionAllowed=false olması yeni event için ayrı policy ret koşuludur.

    Message/event evidence
    SSE connection accepted
    Policy context review
    Subscription allowed=false
    Delivery conclusion
    Delivery pending
  2. Event ile stream lifetime ayrıldı

    SSE server’dan client’a event taşır. Daha önce kabul edilmiş subscription veya cursor, yeni event için resource permission yerine geçmez.

    Message/event evidence
    Direction: server → client
    Policy context review
    Cursor ≠ permission
    Delivery conclusion
    New event gate required
  3. Negatif delivery sonucu eşleştirildi

    expectedAllowed=false, expectedResourceDelivery=false ve expectedBody=null’dır. Beklenen yokluk yeni title event’inin client’a taşınmamasıdır.

    Message/event evidence
    Allowed=false
    Policy context review
    Resource delivery=false
    Delivery conclusion
    Body=null
  4. Historical data silindi sayılmadı

    Bu ret daha önce teslim edilmiş title’ın yok edildiğini göstermez. Yeni delivery sınırı ile geçmiş client data lifetime’ı farklı sorulardır.

    Message/event evidence
    New event withheld
    Policy context review
    Old delivery not retracted
    Delivery conclusion
    Mutation=false
  5. Revocation propagation kanıtı istenildi

    Row subscriptionAllowed=false’ı önkoşul verir. Bu değerin bütün subscriber’lara ne zaman yayıldığını görmek için adapter ve policy revision gözlemi gerekir.

    Message/event evidence
    Declared revocation known
    Policy context review
    Propagation evidence missing
    Delivery conclusion
    Distributed result UNKNOWN
  6. Event sonucu diğer protokole taşınmadı

    Bu SSE gate’i gRPC veya SOAP’ın otomatik aynı kararı verdiğini kanıtlamaz. SOAP Body action’ı ve gRPC method/message kendi approved handler policy’sine bağlanır.

    Message/event evidence
    SSE denial known
    Policy context review
    RPC/SOAP adapters separate
    Delivery conclusion
    No universal enforcement claim

Context eksik

  1. Missing context kaydı seçildi

    unknownEvidence contextPresent=false ve permission=null içerir. Bu known field denial veya expired row ile aynı evidence durumu değildir.

    Message/event evidence
    Context present=false
    Policy context review
    Permission=null
    Delivery conclusion
    Decision pending
  2. Permission hesaplanmadığı korundu

    Subject, tenant, action ve resource context’i bulunmadığı için permission sonucu bilinmez kalır. Channel alias’ını actor authority diye kullanmak bu boşluğu doldurmaz.

    Message/event evidence
    Policy inputs missing
    Policy context review
    Permission UNKNOWN
    Delivery conclusion
    No guessed actor
  3. Güvenli sonuç ayrı belirlendi

    expectedAllowed=false ve expectedResourceDelivery=false güvenli sonuçtur. Bu boolean, eksik permission kanıtının verified false’a dönüştüğü anlamına gelmez.

    Message/event evidence
    Safe allow=false
    Policy context review
    Knowledge remains UNKNOWN
    Delivery conclusion
    Delivery=false
  4. Body ve mutation yokluğu birlikte tutuldu

    expectedBody=null ve expectedMutation=false’tur. İnceleme yalnız error metnine değil, resource delivery ve write’ın gerçekleşmemesi koşullarına da bakar.

    Message/event evidence
    Body=null
    Policy context review
    Mutation=false
    Delivery conclusion
    Negative boundaries retained
  5. Cost budget permission sayılmadı

    titleWeight=1 ve listLimit=10 bu profile ait maliyet tercihidir. Bunlar universal GraphQL sabitleri veya eksik identity yerine kullanılacak gate’ler değildir.

    Message/event evidence
    Selected cost policy
    Policy context review
    Cost ≠ identity
    Delivery conclusion
    Context still missing
  6. Unknown nedeni teşhis için bırakıldı

    Known deny ve context loss ayrı reason’larla izlenmelidir. No-delivery güvenli olsa da hangi trust kaynağının eksik olduğu bulunmadan policy’nin doğru çalıştığı söylenmez.

    Message/event evidence
    No delivery known
    Policy context review
    Missing provenance unresolved
    Delivery conclusion
    No clean policy claim

UYGULAMA · GÜVENLİK KONTROLÜ · DOĞRULAMA

Bir policy, farklı delivery biçimleri

Blue tasarımında readTitle kararı actor, tenant, note-A, action ve property girdileriyle tanımlanır. GraphQL resolver, WebSocket message handler, SSE event filter ve gRPC method aynı policy sonucunu kendi delivery formatına taşır; sadece connection seviyesinde kontrol bırakılmaz. SOAP için de parser’dan çıkan Body action’ı approved application handler’a bağlanır. Bunun tek global boolean olması gerekmez: resource policy ve field projection ayrı ve okunabilir kalabilir. Cost/size sınırı permission gate’inden bağımsız bir bütçedir. Subscription expiry ve revocation davranışının uygulama tarafından belirlendiği belgelenir; açık bir channel’a sonsuz identity ömrü verilmez. Cache key’leri ve batch context’i policy girdilerini kaybetmez. Client’a gönderilen hata güvenli ve anlaşılır olurken internal karar nedeni, actor context ve policy revision erişim kontrollü telemetry’de tutulur.

Sonuç kadar yokluğu da doğrulamak

Olumlu fixture, izinli read’in title projection’ını üretmesini kontrol eder; olumsuz fixture aynı zamanda store delivery=0, mutation=false ve protectedBody=null sonuçlarını kontrol eder. GraphQL field denial için null+errors shape’i seçilen nullable schema ile uyumlu olmalıdır; HTTP status buradan otomatik türetilmez. WebSocket’te daha önce kabul edilmiş connection’ın zaman sınırında yeni message’ı açmadığı, SSE’de revoked subscription’ın yeni event’i client’a taşımadığı ayrı satırlardır. Missing-policy dalı false ile aynı kanıt değildir: permissionUnknown olarak saklanıp güvenli sonuç deny seçilir. Bu ayrım operasyonel teşhiste yararlıdır; reddin gerçekten policy sonucu mu yoksa context kaybı mı olduğunu gösterir. Animasyon bütün bu sonuçları supplied ledger üzerinden deterministik oynatır. Gerçek browser Origin/Cookie enforcement, stream backpressure, RPC server veya subscription adapter için ayrıca entegrasyon kanıtı gerekir.

ŞİMDİ VAKAYA UYGULA

Connection, schema ve budget geçse bile hangi gate yeni delivery’yi durdurur?

GraphQL field, WebSocket message ve SSE event kendi güncel policy koşulunu ister. Null protected body, nullable error envelope ve missing context farklı sonuçlardır.

Vakadaki doğrulanmış actor, tenant ilişkisi ve requested action için gereken kararları ayır. Authentication veya proof başarısını object permission yerine kullanma.

Bağlı vaka dosyasını aç ↗

ÖRNEĞİ BİRLİKTE OKUYALIM

Atlas Notları — karar defteri

Bir alan seç; hangi sonucu desteklediğini ve nerede yetersiz kaldığını incele.

Ham kaydı ve alan açıklamalarını oku
{
  "profile": {
    "noteId": "note-A",
    "title": "Tea & Bread",
    "actor": "Duru",
    "tenant": "tenant-A",
    "action": "notes.read",
    "field": "title",
    "now": 120,
    "selectedNullableTitle": true,
    "actualProtocols": false
  },
  "rows": [
    {
      "case": "normal",
      "channel": "graphql",
      "connectionAccepted": true,
      "contextPresent": true,
      "current": true,
      "objectAllowed": true,
      "fieldAllowed": true,
      "subscriptionAllowed": true,
      "costAllowed": true,
      "expectedAllowed": true,
      "expectedBody": {
        "title": "Tea & Bread"
      },
      "expectedResourceDelivery": true,
      "expectedMutation": false
    },
    {
      "case": "field-denied",
      "channel": "graphql",
      "connectionAccepted": true,
      "contextPresent": true,
      "current": true,
      "objectAllowed": true,
      "fieldAllowed": false,
      "subscriptionAllowed": true,
      "costAllowed": true,
      "expectedAllowed": false,
      "expectedBody": null,
      "expectedResourceDelivery": false,
      "expectedMutation": false,
      "graphqlEnvelope": {
        "data": {
          "note": {
            "title": null
          }
        },
        "errors": [
          {
            "message": "Field not permitted",
            "path": [
              "note",
              "title"
            ]
          }
        ]
      }
    },
    {
      "case": "expired",
      "channel": "websocket",
      "connectionAccepted": true,
      "contextPresent": true,
      "current": false,
      "validUntil": 120,
      "objectAllowed": true,
      "fieldAllowed": true,
      "subscriptionAllowed": true,
      "costAllowed": true,
      "expectedAllowed": false,
      "expectedBody": null,
      "expectedResourceDelivery": false,
      "expectedMutation": false
    },
    {
      "case": "revoked",
      "channel": "sse",
      "connectionAccepted": true,
      "contextPresent": true,
      "current": true,
      "objectAllowed": true,
      "fieldAllowed": true,
      "subscriptionAllowed": false,
      "costAllowed": true,
      "expectedAllowed": false,
      "expectedBody": null,
      "expectedResourceDelivery": false,
      "expectedMutation": false
    }
  ],
  "costPolicy": {
    "titleWeight": 1,
    "listLimit": 10,
    "specUniversalConstants": false
  },
  "protocolLedger": [
    {
      "protocol": "GraphQL",
      "unit": "operation/field",
      "permission": "object + field",
      "transportStatusDerived": false
    },
    {
      "protocol": "WebSocket",
      "unit": "application message",
      "permission": "current actor + action + object",
      "originIsNonBrowserIdentity": false
    },
    {
      "protocol": "SSE",
      "unit": "subscription/event",
      "direction": "server to client",
      "cursorIsPermission": false,
      "exactlyOnce": false
    },
    {
      "protocol": "gRPC",
      "unit": "service method and streamed message",
      "modes": [
        "unary",
        "server-streaming",
        "client-streaming",
        "bidirectional-streaming"
      ],
      "channelCredentialsAreMethodPermission": false
    },
    {
      "protocol": "SOAP 1.2",
      "unit": "Envelope / optional Header / required Body",
      "coreProvidesUniversalAuthz": false
    }
  ],
  "unknownEvidence": {
    "contextPresent": false,
    "permission": null,
    "expectedAllowed": false,
    "expectedBody": null,
    "expectedResourceDelivery": false,
    "expectedMutation": false
  },
  "boundaries": {
    "actualResolver": false,
    "actualOriginCookieEnforcement": false,
    "actualStream": false,
    "actualRPC": false,
    "actualSOAP": false
  }
}
rows
Channel kabulü ve güncel permission conjunction’ı; null korunan title’ın yokluğudur.
protocolLedger
Protocol biçimi ile business kararının karşılaştırması; gerçek wire capture değildir.
unknownEvidence
Eksik context ayrı unknown kanıtı ve güvenli deny sonucudur.

Sabit public note ledger’ı; gerçek query, socket, EventSource, protobuf veya SOAP XML çalışmaz.

İki yanlış kanı

Schema geçerliyse her field okunabilir.

Schema validation ile object/field authorization farklı kararlardır.

Açık stream sürekli permission demektir.

Yeni message/event için güncel context gerekir; cursor permission değildir.

SIRA SENDE

Bu hikâyeyi sen çöz.

Sonucu tahmin et, kanıtın sınırını bul ve nedenini kendi cümlenle anlat.

WebSocket connectionAccepted=true, fakat now=validUntil=120 ve current=false. Sonraki message için note body gönderilir mi?

  1. Hayır. expectedResourceDelivery=false.
  2. Evet. İlk handshake bütün sonraki message’ları süresiz authorize eder.
Gerekçeli cevabı oku

Hayır. expectedResourceDelivery=false. — Kurulmuş connection süresi dolan authorization context’ini geçerli yapmaz. Bu message için body ve mutation yoktur.

Field-denied için expectedBody=null, fakat GraphQL envelope data ve errors içeriyor. Protected title’ın teslim edildiği anlamına mı gelir?

Dersten seçilen artifact alanları; öğretim örneği

rows[1].fieldAllowed
false
rows[1].expectedBody
null
rows[1].graphqlEnvelope
{"data":{"note":{"title":null}},"errors":[{"message":"Field not permitted","path":["note","title"]}]}
  1. Evet. Envelope’da data kelimesi varsa bütün title değerleri açılmıştır.
  2. Hayır. Nullable title null; errors field ret nedenini bildirir.
Gerekçeli cevabı oku

Hayır. Nullable title null; errors field ret nedenini bildirir. — Bu schema’da title nullable. data.note.title=null protected title verisi değildir. Data+errors şekli tek başına belirli HTTP status’u da kanıtlamaz.

SSE subscription revoked olunca connection açık kalsa da event duruyor. gRPC method ve streamed message için aynı ayrım neden gerekir?

Gerekçeli cevabı oku

Channel kurulması sonraki event veya message’lara genel izin vermez. SSE cursor continuation bilgisidir; subscription izni veya exactly-once değildir. gRPC channel credential’ları service method ve streamed message policy’sinin yerine geçmez. GraphQL’de object yanında field ve cost koşulları da gerekir; burada cost değerleri profile’a ait, universal spec sabitleri değildir. Context yoksa delivery durur; gerçek resolver, stream, RPC veya SOAP çalıştırılmaz.

□ Channel kabulünü per-operation authorization saymadım.

□ Subscription/cursor ve cost policy kapsamlarını ayrı belirttim.

Uygulama konsolunu aç · request / response / browser
Request, URL, cookie ve DOM örneklerini ayrıca aç

Kaynaklar ve kapsam