Şartname

Uyum kanıtı attestation'ı, sürüm 1.

https://attestkeep.com/attestation/compliance-evidence/v1, Attestkeep'in bir uyum raporu üzerine imzaladığı her attestation'ın predicateType değeridir. Sizi bu adrese bir belge getirdiyse, o belgenin tanımı bu sayfadır: iddia, her alan, zarf, imzalanan kodlama ve doğrulayabileceğiniz gerçek bir örnek.

Ortaya konan iddia

Tek cümleyle: bu uyum raporunu bu kurulum üretti ve rapor o günden beri değiştirilmedi. İddianın tamamı bu; aşağıdaki her şey bundan türer.

İddia, tedarik zinciri dünyasının bu tür şeyler için zaten kullandığı formatla taşınır — DSSE zarfı içinde bir in-toto bildirimi, Ed25519 ile imzalı — kendi tasarımımız bir imza şemasıyla değil. Bu tercih bilinçli: yalnızca bizim doğrulayabileceğimiz bir format bizi darboğaz yapardı, oysa belgenin değeri tam olarak denetçinin onu biz odada yokken denetleyebilmesidir. İmza anahtarı kurulumun içinde üretilir ve oradan hiç çıkmaz; dünyadan güvenmesi istenen tek şey açık yarısıdır.

Bildirim ve konusu

Zarfın payload'ı sürüm 1 bir in-toto bildirimidir. Dış alanları:

AlanTipAnlamı
_typestring Her zaman https://in-toto.io/Statement/v1.
subjectdizi İddianın konusu olan raporu adlandıran tek bir kaynak tanımlayıcısı: name raporun kimliğidir; digest.sha256, üretilen baytların SHA-256'sıdır — 64 küçük harf hex karakter, başında sha256: öneki olmadan.
predicateTypestring Her zaman https://attestkeep.com/attestation/compliance-evidence/v1 — bu sayfanın adresi.
predicatenesne İddianın kendisi; her alanı bir sonraki bölümde tanımlı.

Bildirim bir belge hakkındadır, dolayısıyla konusu o belgedir. Raporun kendisi attestation'ın içinde taşınmaz ve bu bilinçlidir: rapor büyüktür ve okur onu PDF ya da CSV çıktısı olarak tutuyor olabilir. Kanıtlanması gereken şey, eldeki kopyanın imzalanan kopya olduğudur; bir özet bunu baytların her kopyası için cevaplar — içeriğin bir sureti ise yalnızca o suret için cevaplardı.

Çerçeve ve denetim dönemi imzanın içindedir, konunun hemen yanında. Aynı dönem iki ayrı çerçeveye göre değerlendirildiğinde iki ayrı belge çıkar ve okur birini öbürü diye etiketleyememelidir. Bildirimdeki hiçbir şey — konu, özet, dönem, çerçeve, zaman damgaları — imzadan sonra doğrulama düşmeden değiştirilemez.

Predicate alanları

İsteğe bağlı alanlar boşken JSON'dan tümüyle çıkarılır, asla yer tutucuyla yazılmaz. Kurulumun elinde olmayan bir zaman damgası boş dize olarak yazılır, uydurma bir tarih olarak değil.

AlanTipAnlamı
report_idstring Belgenin kimliği; raporun üstünde basılı olanla aynı, böylece elinizdeki attestation'ın elinizdeki rapora ait olduğu bir bakışta görülür. Subject'teki name değerini tekrarlar.
frameworkstring Raporun hangi uyum eşlemesine göre derlendiği, örneğin soc2. İmzanın içindedir ki bir çerçevenin raporu başka çerçevenin raporu diye etiketlenemesin.
periodnesne Raporun kapsadığı denetim penceresi.
period.start, period.endstring RFC 3339 zaman damgaları, UTC'ye normalize edilmiş. Telde dize olarak dururlar, çünkü imzalanan şey baytların ta kendisidir.
installationnesne İmzacıyı, kümeyi tarif etmeden kimliklendirir.
installation.fingerprintstring Lisansın bağlandığı opak küme tanımlayıcısı — bir hash; topoloji yok, isim yok, müşterinin binadan çıkan bir belgeye koymaya itiraz edeceği hiçbir şey yok.
installation.license_idstring, isteğe bağlı Yayıncının, kurulumun o sırada lisanslı olduğunu teyit etmesini sağlar — "bu dosyaya dokunulmamış" ile "gerçek bir kurulumdan geldi" arasındaki bağ.
installation.binding_idstring, isteğe bağlı Kurulumun aktivasyonda kullandığı lisans bağı; aynı teyide hizmet eder.
generated_atstring Kurulumun raporu ürettiği an, kendi anladığı haliyle — RFC 3339 UTC. İmzacının beyanıdır, kanıt değil: belgeyi güvenilir bir saate bağlayan hiçbir şey yoktur; buna ihtiyacı olan okur onu başka yerden bulmalıdır.
generated_bystring, isteğe bağlı Raporu isteyen operatör, raporun kendisinin kaydettiği haliyle.
generatornesne Raporu üreten yazılım.
generator.name, generator.versionstring Hangi sürümün uyum eşlemelerinin yürürlükte olduğu. Eşlemeler, çerçeveler daha dikkatli okundukça değişir; hangi okumayı kullandığını söylemeyen kanıt sonradan yeniden incelenemez.

DSSE zarfı

Bildirim, şu şekle sahip bir DSSE zarfının içinde taşınır:

{
  "payload":     "<bildirim JSON'unun standart base64'ü>",
  "payloadType": "application/vnd.in-toto+json",
  "signatures": [
    { "keyid": "ak-…", "sig": "<Ed25519 imzasının base64'ü>" }
  ]
}
  • payload, bildirimin serileştirilmiş baytlarının dolgulu standart base64'üdür. Bildirim bir kez serileştirilir: imzalanan baytlar, iletilen baytların ta kendisidir.
  • payloadType imzalanan şeyin parçasıdır (aşağıdaki kodlamaya bakın); böylece bir in-toto bildirimi üzerine atılmış imza, aynı baytların başka türde okunuşu üzerine imza diye sunulamaz.
  • sig, PAE(payloadType, payload) üzerine atılmış bir Ed25519 imzasıdır (RFC 8032) — base64 dizesi üzerine değil, ön kimlik doğrulama kodlaması üzerine.
  • keyid açık anahtardan türetilir: "ak-" artı 32 baytlık anahtarın SHA-256'sının ilk 16 hex karakteri. Türetildiği için adlandırdığı anahtarla çelişemez; ve yalnızca bir ipucudur — doğrulayıcı, zaten güvendiği bir anahtarla denetler, zarfın kendisine söylediği bir anahtarla asla.
  • Bir zarf birden çok imza taşıyabilir. Doğrulayıcı her girdiyi güvendiği anahtara karşı dener ve herhangi biri doğrulanırsa zarfı kabul eder.

PAE kodlaması

İmzalanan şey, payload ile türünün birlikte ön kimlik doğrulama kodlamasıdır:

PAE(type, body) = "DSSEv1" SP LEN(type) SP type SP LEN(body) SP body

Burada SP tek bir boşluk, LEN ondalık ASCII yazılmış bayt uzunluğudur. Uzunluklar baytı sayar, karakteri asla. Örneğin PAE("http://example.com/HelloWorld", "hello world") şu bayt dizisidir: DSSEv1 29 http://example.com/HelloWorld 11 hello world.

DSSE'nin bütün güvenliği bu tek fikirdedir. Yalnızca payload imzalansaydı, bir in-toto bildirimi üzerine atılan imza, aynı baytları başka bir payloadType altında taşıyan bambaşka bir şeyin imzası diye sunulabilirdi. PAE ikisini uzunluk önekleriyle birbirine bağlar; hiçbiri öbürünün parçası gibi gösterilemez.

Sertifika zinciri

Zarfın imzası raporun değişmediğini kanıtlar ve bir anahtar adlandırır. Ama o anahtarın kime ait olduğunu tek başına kanıtlayamaz: açık anahtarı belgeyi getirenden alan bir doğrulayıcı, yalnızca belgenin kendi içinde tutarlı olduğunu göstermiş olur. Lisans sertifikası bu boşluğu kapatır. Attestkeep'in her lisanslı kurulum için imzaladığı bir belgedir ve kurulumun kanıt imza anahtarını imzanın içinde taşır — böylece tek bir Attestkeep anahtarına güvenen okur, herhangi bir kurulumun raporunu doğrulayabilir:

Attestkeep kök anahtarı
  └─ imzalar → lisans sertifikası (compact JWT)
                └─ cnf.jwk adlandırır → kurulumun kanıt anahtarı
                                          └─ imzalar → DSSE zarfı
                                                         └─ subject özeti sabitler → rapor

Kök anahtar. Bu sayfadan TLS üzerinden alınan şu değer, zincirin tek güven çıpasıdır:

kid:     ak1
ed25519: e287aabe4712197cfa5b6fdf9ea8f2d7f0333ce16ca69aac7e4a3f1e84c04179

Sertifika bir compact JWT'dir (RFC 7515): base64url(header) "." base64url(payload) "." base64url(signature); base64url paddingsizdir (RFC 4648 bölüm 5 — = yok). Header {"alg":"EdDSA","typ":"JWT","kid":"ak1"} şeklindedir; doğrulayıcı EdDSA dışındaki her alg değerini reddetmek zorundadır — klasik JWT düşürme saldırıları (alg=none, algoritma karışıklığı) böylece yapısal olarak dışarıda kalır. İmza, header_b64 "." payload_b64 ASCII baytları üzerinde Ed25519'dur.

Zincir doğrulayıcısının okuduğu payload alanları (bilinmeyen alanlar yok sayılmalıdır — imzacı alan ekleyebilir):

AlanTürAnlamı
substring Sertifikanın verildiği lisansın kimliği.
fprstring Lisansın bağlandığı küme parmak izi — predicate'teki installation.fingerprint ile eşit olmak zorunda olan değer.
planstring Plan kodu; zincir doğrulayıcısı için bilgi amaçlı.
iat, expnumber Veriliş ve bitiş, unix saniye. exp 0 ise sertifika süresizdir.
jtistring Sertifikanın serisi.
cnf.jwkstring RFC 7800'ün confirmation claim'i: kurulumun Ed25519 kanıt açık anahtarı, tam 64 hex karakter. İç içe bir JWK nesnesi değil — ham 32 bayt, hex kodlanmış. Bu alanı taşımayan sertifika hiçbir anahtara kefil değildir ve zincire çıpa olamaz.

Bir raporu zincir üzerinden doğrulamak için:

  1. Sertifikayı . üzerinden tam üç parçaya ayırın; header'ı çözün ve alg EdDSA değilse reddedin.
  2. header_b64 "." payload_b64 ASCII baytları üzerindeki Ed25519 imzasını yukarıdaki kök anahtarla doğrulayın.
  3. Payload'ı çözüp cnf.jwk'i okuyun — kurulumun kanıt anahtarı budur.
  4. DSSE zarfını o anahtarla, yukarıdaki bölümlerin anlattığı gibi doğrulayın.
  5. Çapraz kontrol: bildirimdeki predicate.installation.fingerprint, sertifikadaki fpr ile eşit olmak zorundadır. Bu adım olmasa gerçek bir sertifika, başka bir kurulumun gerçek zarfının yanına konabilirdi. installation.license_id varsa ve sub'dan farklıysa okuru uyarın.

Süre bilgidir, ret sebebi değil. Sertifikalar otuz günde bir yenilenir ve geçen çeyreğin raporuna o dönemin sertifikası kefildir — süresi geçmiş sertifikayı reddetmek, eski her raporu doğrulanamaz yapardı. Doğrulayıcı süresi geçmiş sertifikanın tarihini söylemeli, yargıyı okura bırakmalıdır.

Eksiksiz bir örnek

Bu zarfı referans imzacı üretti. Bilerek herkese açık bir test anahtarıyla imzalandı — Ed25519 tohumu 0x01'den 0x20'ye kadar olan baytlar — yani formatı gösterir, herhangi bir gerçek raporun menşeini değil. Gerçek attestation'lar her kurulumun içinde üretilen ve oradan hiç çıkmayan bir anahtarla imzalanır.

{
  "payload": "eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjEiLCJzdWJqZWN0IjpbeyJuYW1lIjoicnB0LTlmMmM3YTQxZDBiODNlNTYiLCJkaWdlc3QiOnsic2hhMjU2IjoiNzQ3YjgzZWNkMTY2OTEyNjk2NmVlNjAyZTM3MjI0NTE2Y2M5YmMyZGQ5NWFhZWJlNDIwZWQxY2IzNGVkZWMwYyJ9fV0sInByZWRpY2F0ZVR5cGUiOiJodHRwczovL2F0dGVzdGtlZXAuY29tL2F0dGVzdGF0aW9uL2NvbXBsaWFuY2UtZXZpZGVuY2UvdjEiLCJwcmVkaWNhdGUiOnsicmVwb3J0X2lkIjoicnB0LTlmMmM3YTQxZDBiODNlNTYiLCJmcmFtZXdvcmsiOiJzb2MyIiwicGVyaW9kIjp7InN0YXJ0IjoiMjAyNi0wNy0wMVQwMDowMDowMFoiLCJlbmQiOiIyMDI2LTA3LTMxVDIzOjU5OjU5WiJ9LCJpbnN0YWxsYXRpb24iOnsiZmluZ2VycHJpbnQiOiIzZjdiMWE5ZTVjMmQ4ZjA0YTZiM2UxYzdkOTA1MmU4YTFiNGY2YzNkN2U5YTBiMmM0ZDZlOGYwYTFiM2M1ZDdlIiwibGljZW5zZV9pZCI6ImxpYy03YzMxZjBkMiIsImJpbmRpbmdfaWQiOiJiaW5kLWE5NGUyYzE3In0sImdlbmVyYXRlZF9hdCI6IjIwMjYtMDgtMDFUMDY6MDA6MDBaIiwiZ2VuZXJhdGVkX2J5IjoiYXVkaXRvckBleGFtcGxlLmNvbSIsImdlbmVyYXRvciI6eyJuYW1lIjoiYXR0ZXN0a2VlcCIsInZlcnNpb24iOiIwLjEuMCJ9fX0=",
  "payloadType": "application/vnd.in-toto+json",
  "signatures": [
    {
      "keyid": "ak-65b60673d6ed884b",
      "sig": "68F6kgLmLYYMYa2wHzdOZMZFQN7NJ5prDRfR7pcpwI+kqYl9ARr+VpfOoyiJmnh01N8HG6ze/1bExrUgTugTBg=="
    }
  ]
}

Payload şu bildirime çözülür:

{
  "_type": "https://in-toto.io/Statement/v1",
  "subject": [
    {
      "name": "rpt-9f2c7a41d0b83e56",
      "digest": {
        "sha256": "747b83ecd1669126966ee602e37224516cc9bc2dd95aaebe420ed1cb34edec0c"
      }
    }
  ],
  "predicateType": "https://attestkeep.com/attestation/compliance-evidence/v1",
  "predicate": {
    "report_id": "rpt-9f2c7a41d0b83e56",
    "framework": "soc2",
    "period": {
      "start": "2026-07-01T00:00:00Z",
      "end": "2026-07-31T23:59:59Z"
    },
    "installation": {
      "fingerprint": "3f7b1a9e5c2d8f04a6b3e1c7d9052e8a1b4f6c3d7e9a0b2c4d6e8f0a1b3c5d7e",
      "license_id": "lic-7c31f0d2",
      "binding_id": "bind-a94e2c17"
    },
    "generated_at": "2026-08-01T06:00:00Z",
    "generated_by": "auditor@example.com",
    "generator": {
      "name": "attestkeep",
      "version": "0.1.0"
    }
  }
}

Onu doğrulayan açık anahtar, doğrulayıcının beklediği biçimde:

79b5562e8fe654f94078b112e8a98ba7901f853ae695bed7e0e3910bad049664

Zarfı ve anahtarı tarayıcı doğrulayıcısına yapıştırın, geçer; payload'ın tek bir karakterini değiştirin, düşer.

Attestation doğrulamak

Üç yol, bağımsızlık sırasıyla:

  • bu sitedeki doğrulama sayfası — tamamen tarayıcınızda çalışır, hiçbir yere bir şey göndermez;
  • DSSE ve in-toto bilen herhangi bir araç — formatta bize özel hiçbir şey yok;
  • istediğiniz dilde kendi on satırınız: lisans sertifikasını kök anahtarla doğrulayın, kurulumun anahtarını cnf.jwk'den alın, payload'ın base64'ünü çözün, PAE'yi kurun, Ed25519 imzasını o anahtarla doğrulayın ve bildirimi ancak ondan sonra okuyun.

Hangisini seçerseniz seçin güven çıpası aynıdır: Attestkeep'in kök anahtarı — kurulumun anahtarına, yukarıda anlatıldığı gibi lisans sertifikası üzerinden kefil olur. Anahtar hiçbir zaman belgenin kendisinden alınmaz (belgedeki keyid bir etikettir, kimlik belgesi değil) ve raporu teslim edenin beyanına da güvenilmez: elden verilen bir anahtar zarfı yine doğrular, ama yalnızca iç tutarlılığı gösterir, menşei değil. Sınırlar da aynıdır: geçerli bir zincir, belgenin değişmediğini ve hangi kurulumun imzaladığını kanıtlar. Hukuki bir elektronik imza değildir ve imzalamanın ne zaman olduğunu kanıtlamaz — generated_at da dönem de kurulumun kendi beyanıdır. İki sınır da doğrulama sayfasında açıkça yazılıdır.

Son güncelleme: 29 Ağustos 2026