Reference documentation for KSeF certificate types, generation, and usage. Based on official gov.pl documentation and hands-on testing (February 2026).
KSeF issues its own certificates for system access. These are not qualified electronic signatures (like those from Certum or SimplySign) — they are certificates generated within the KSeF system itself at ap.ksef.mf.gov.pl.
Since February 1, 2026, KSeF certificates are the primary authentication method. Token-based authentication is being phased out and will be fully removed by January 1, 2027.
KSeF generates two distinct certificate types. A single certificate cannot serve both purposes — they must be generated separately.
| Type 1: Authentication | Type 2: Offline | |
|---|---|---|
| Purpose | Login to KSeF (interactive and batch sessions) | Issue invoices in offline/emergency mode |
| Use case | Querying and downloading invoices via API | Issuing invoices when KSeF is unavailable |
| Portal label | "Uwierzytelnienie w systemie KSeF" | "Podpis linku do weryfikacji wystawcy" |
| Relevant for us | Yes — required for invoice sync | No |
Our app downloads invoices from KSeF. This requires a Type 1 certificate to authenticate API sessions. When generating a certificate in the KSeF portal, the user must select "Uwierzytelnienie w systemie KSeF".
Certificates generated by an individual in the KSeF Taxpayer Application (ap.ksef.mf.gov.pl) are always tied to the person, identified by:
- PESEL — for employees or individuals acting on behalf of a company
- NIP — for sole proprietors (jednoosobowa działalność gospodarcza)
Key characteristics:
- The certificate belongs to the person, not any specific company
- One certificate works for all companies the person is authorized to act for
- When used, the person's identity (name, PESEL) is visible in KSeF logs
- Only the named individual may use the certificate — sharing is prohibited
Example from the KSeF portal certificate list:
Identyfikator podmiotu: PESEL: xxxxxxxxxxx
Nazwa właściciela: JAN KOWALSKI
Przeznaczenie: Uwierzytelnienie
Issued to a legal entity (e.g., sp. z o.o., SA) using the company's NIP. Requires authentication via qualified electronic seal (pieczęć elektroniczna).
Key characteristics:
- Tied to the company NIP, not any individual
- Multiple certificates can be generated per company
- The company distributes certificates to employees as needed
- When used, only company data appears in KSeF — individual identity is hidden
- The company is responsible for certificate lifecycle management
We do not currently use organization certificates. The portal at ap.ksef.mf.gov.pl generates person certificates. Organization certificates require a qualified electronic seal, which is a separate procurement.
- Login — authenticate with trusted profile (profil zaufany), qualified e-signature, or e-ID
- Password — enter a password to protect the private key
- Private key generated — the browser generates a key pair; the private key is saved to the user's device as a named file (e.g.,
test-111) - Choose purpose:
- "Podpis linku do weryfikacji wystawcy" (Type 2 — offline)
- "Uwierzytelnienie w systemie KSeF" (Type 1 — authentication)
- Set validity — start date configurable, valid for 2 years from that date
- Certificate issued — available for download
The portal produces:
- A private key file (
.key) — saved to the device during generation - A certificate file (
.crt/.pem) — downloadable after generation
These correspond to our .key + .crt upload mode, which converts them server-side to PKCS12 format for xmlsec1 signing.
The certificate proves the signer's identity, but it does not determine which company they act for. That is specified in the API request:
1. App sends: getChallenge(NIP = "1234567890", Type = "onip")
↑ company NIP
2. KSeF returns: challenge string
3. App signs challenge with person's certificate (XADES/xmlsec1)
↑ proves identity (PESEL-based)
4. KSeF verifies:
- Is the certificate valid?
- Is the certificate holder authorized for NIP 1234567890?
- If yes → issue tokens
The same certificate can authenticate for any company where the person has KSeF authorization. The NIP in the request determines the company context, not the certificate.
For a person's certificate to work for a company, that person must be authorized in KSeF for that company's NIP. Authorization is managed in the KSeF portal by the company's administrator or legal representative.
| Property | Value |
|---|---|
| Maximum validity | 2 years from start date |
| Start date | Configurable at generation time |
| Revocation | Can be revoked in the KSeF portal |
| Renewal | Generate a new certificate before expiry |
| Multiple active | A person can have multiple active certificates |
Company A (NIP: 1234567890) → Credential row with cert data
Company B (NIP: 0987654321) → Credential row with same cert data (re-uploaded)
This forces the user to upload the same certificate file for each company — redundant and confusing, since the certificate belongs to the person.
User → One credential row with cert data
├── authenticates as Company A (NIP: 1234567890)
└── authenticates as Company B (NIP: 0987654321)
The certificate should be stored on the user, and used with whichever company NIP is selected. The NIP for the getChallenge request comes from the company, not the certificate.
- Move
certificate_data_encryptedandcertificate_password_encryptedfrom the credential (company-scoped) to the user or a new user-certificate entity - Keep company-specific fields (tokens,
last_sync_at, NIP) on a per-company record - Certificate upload becomes a user-level action, not a per-company action
- Sync workers still authenticate per-company, but share the user's certificate
| Resource | URL |
|---|---|
| KSeF certificate overview (gov.pl) | https://ksef.podatki.gov.pl/informacje-ogolne-ksef-20/certyfikaty-ksef/ |
| Certificate types explained | https://akademialtca.pl/blog/czy-certyfikat-musi-byc-przypisany-do-osoby-fizycznej |
| KSeF Taxpayer Application | https://ap.ksef.mf.gov.pl |
| KSeF Test Environment | https://ksef-test.mf.gov.pl |
| KSeF Production Environment | https://ksef.mf.gov.pl |