Skip to content

Zawężenie uprawnień przy uwierzytelnianiu certyfikatem KSeF — jak zbudować integrację tylko do odczytu? #838

Description

@mlotocki2k

Problem

Buduję aplikację, która ma wyłącznie odczytywać dane z KSeF: pobieranie metadanych faktur, pobieranie faktur i UPO. Aplikacja nigdy nie wystawia faktur, nie nadaje uprawnień, nie generuje tokenów ani certyfikatów.

Przy tokenie KSeF scenariusz jest rozwiązany wprost: podczas generowania tokenu (POST /tokens) wskazuję zakres permissions — np. tylko InvoiceRead — i token fizycznie nie jest w stanie zrobić nic więcej. Wyciek tokenu = wyciek dostępu do odczytu w jednym kontekście. Ryzyko ograniczone i policzalne.

Przy certyfikacie KSeF nie widzę takiej możliwości. Uwierzytelnienie certyfikatem osoby z uprawnieniami właścicielskimi daje pełne uprawnienia właściciela kontekstu. Zweryfikowałem na środowisku testowym — accessToken uzyskany przez XAdES-BES z certyfikatem KSeF zawiera:

"typ": "ContextToken",
"aum": "InternalCertificate",
"per": ["Owner"],
"pec": [], "rol": [], "pep": [], "iop": []

Czyli pełne uprawnienia właścicielskie, mimo że aplikacji potrzebny jest wyłącznie odczyt. Nie znalazłem w API żadnego parametru pozwalającego to zawęzić — ani przy wniosku o certyfikat, ani przy uwierzytelnianiu.

Konsekwencja bezpieczeństwa

Aby działać automatycznie (bez interakcji użytkownika przy każdym odświeżeniu sesji), aplikacja musi przechowywać certyfikat wraz z kluczem prywatnym. Wyciek tego pliku oznacza, że osoba trzecia uzyskuje pełne uprawnienia właścicielskie do podmiotu — może wystawiać faktury, nadawać uprawnienia kolejnym osobom, generować tokeny i następne certyfikaty. A nie tylko czytać faktury, do czego podatnik faktycznie upoważnił aplikację.

To odwrotność zasady najmniejszych uprawnień. Podatnik nie ma technicznej możliwości ograniczyć tego, co aplikacja może zrobić w jego imieniu — może jedynie zaufać deklaracji dostawcy oprogramowania.

Pytania

  1. Czy istnieje obecnie sposób, aby uwierzytelnienie certyfikatem KSeF dawało zawężony zakres uprawnień (np. wyłącznie InvoiceRead) zamiast Owner? Jeśli tak — którym mechanizmem?
  2. Jeśli takiego mechanizmu nie ma — czy jest planowany, i w jakim horyzoncie czasowym?
  3. W Czy tokeny KSeF będą obsługiwane po 31 grudnia 2026 r.? #834 padła informacja, że po stronie API przygotowujecie się do utrzymania tokenów KSeF również po 31 grudnia 2026 r. Czy w związku z tym token pozostaje rekomendowaną metodą dla integracji o ograniczonym zakresie uprawnień (read-only, systemy SaaS działające na rzecz wielu podatników), a certyfikat jest przewidziany dla scenariuszy wymagających pełnych uprawnień? Chciałbym wiedzieć, czy budując integrację read-only mam docelowo opierać się na tokenie, czy na certyfikacie.

Propozycje

Od najmniej inwazyjnej dla obecnej architektury:

A. Zakres uprawnień jako parametr wniosku o certyfikat. Analogicznie do permissions w POST /tokens. Uprawnienia efektywne = część wspólna uprawnień osoby i zakresu certyfikatu. Zakres zapisany w certyfikacie (rozszerzenie z własnym OID) albo trzymany po stronie KSeF i wiązany z odciskiem palca certyfikatu.

B. Certyfikat związany z jednym kontekstem (NIP). Certyfikat wystawiany dla wskazanego kontekstu, a nie dla wszystkich, w których osoba ma uprawnienia. Rozwiązuje najgorszy przypadek: biuro rachunkowe wgrywające jeden certyfikat do systemu obsługującego wielu klientów. Wymaga podniesienia limitu aktywnych certyfikatów.

C. Zawężenie zakresu przy uwierzytelnianiu. Opcjonalne pole requestedPermissions w AuthTokenRequest — dobrowolne obniżenie uprawnień przez klienta na czas sesji (accessToken dostaje węższe per). Nie chroni przed wyciekiem samego certyfikatu, ale ogranicza promień rażenia wycieku accessToken/refreshToken i pozwala aplikacji wykazać, że nie robi nic ponad odczyt.

Kontekst

Temat pojawiał się już w #287 (jakie uprawnienia daje uwierzytelnienie certyfikatem), #565 i #461 — zakładam osobne zgłoszenie, bo dotyczy konkretnego, wąskiego przypadku: integracji wyłącznie do odczytu i pytania, jaką metodę uwierzytelniania MF dla niej rekomenduje w świetle ustaleń z #834.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions