Skip to content

SharePoint Online certificate authentication on Linux

directorcia edited this page Oct 14, 2026 · 1 revision

o365-connect-pnp-cert-linux.ps1 generates a file-based certificate, can provision an Entra application for it, and connects PnP.PowerShell to a SharePoint Online site using certificate authentication.

The script is intended to run on Linux in PowerShell 7.4.6 or later. It is not the Windows certificate-store workflow; the private key is kept in an encrypted PFX file and loaded ephemerally when connecting.

Requirements

  • Linux and PowerShell 7.4.6 or later.
  • For connections, PnP.PowerShell 3.0.0 or later.
  • To provision an Entra app, Microsoft.Graph.Authentication 2.0.0 or later, plus an administrator who can sign in and grant the requested application permissions.
  • Network access to the PowerShell Gallery when a required module needs to be installed or updated, and to Microsoft Graph and SharePoint Online.

When allowed to install a missing module, the script installs it for the current user (CurrentUser scope); it does not require sudo. Certificate generation by itself uses .NET and does not require either module.

Choose one operating mode

Exactly one of -GenerateLocalCertificate and -UseCertificateAuth must be specified.

Generate a certificate

./o365-connect-pnp-cert-linux.ps1 -GenerateLocalCertificate

The script prompts for a nonempty PFX password unless -GeneratedPfxPassword or -CertificatePasswordEnvironmentVariable supplies it. It creates:

  • An RSA-2048, SHA-256 self-signed certificate.
  • A public DER-encoded .cer file.
  • An encrypted private-key .pfx file.

Both files are named using the certificate thumbprint. The script prints their paths, the thumbprint, and the expiry date. The private key is not imported into a persistent certificate store.

Useful generation options:

Parameter Purpose Default
-GeneratedCertSubject Certificate common name; also the default app display name when provisioning. O365-PNP-AppAuth
-GeneratedCertYearsValid Certificate lifetime, from 1 through 100 years. 2
-GeneratedCertOutputPath Dedicated directory for the generated files. XDG data path described below
-GeneratedPfxPassword Nonempty SecureString password for the generated PFX. Prompted interactively

Provision an Entra app

Generation can be combined with one-time app provisioning:

./o365-connect-pnp-cert-linux.ps1 `
  -GenerateLocalCertificate `
  -ProvisionEntraApp `
  -Tenant contoso.onmicrosoft.com `
  -SiteUrl https://contoso.sharepoint.com

Provisioning requires an absolute HTTPS -SiteUrl, -Tenant, and an interactive administrator sign-in. The script uses Microsoft Graph device-code authentication. -noprompt/-Headless cannot be used with provisioning.

The script creates an Entra app or reuses the single app with the requested display name, adds the public certificate credential, and ensures the app has these application permissions:

  • SharePoint: Sites.FullControl.All — full control of all SharePoint sites.
  • Microsoft Graph: Application.Read.All — read access to directory applications.

It creates the service principal and role assignments if needed, then saves a connection profile containing the tenant, site URL, app ID, certificate thumbprint, and PFX path. The default profile name is the app display name; -ProfileName can override it. Set -AppDisplayName to choose a different app name. If multiple apps already have that name, provisioning stops rather than choosing one arbitrarily.

The administrator sign-in requests Graph delegated scopes Application.ReadWrite.All and AppRoleAssignment.ReadWrite.All to carry out provisioning. These are setup permissions for the signed-in administrator; the two application permissions listed above are granted to the app being provisioned. Review and approve these privileges according to your organization's policy. New permissions may take time to replicate, so connect from a fresh PowerShell session after provisioning.

-SetupClientId optionally selects a tenant-approved public client ID for Graph device sign-in. Without it, the script uses the Microsoft Graph PowerShell client.

Connect to SharePoint Online

Connect from a saved profile:

./o365-connect-pnp-cert-linux.ps1 `
  -UseCertificateAuth `
  -Tenant contoso.onmicrosoft.com

If more than one saved profile matches the supplied filters, select one explicitly:

./o365-connect-pnp-cert-linux.ps1 `
  -UseCertificateAuth `
  -ProfileName Contoso

Alternatively, supply all connection values directly:

./o365-connect-pnp-cert-linux.ps1 `
  -UseCertificateAuth `
  -Tenant contoso.onmicrosoft.com `
  -SiteUrl https://contoso.sharepoint.com `
  -AppId 11111111-2222-3333-4444-555555555555 `
  -CertificateFilePath /home/admin/auth.pfx

For an interactive connection, the script prompts for the PFX password. The site URL must be an absolute HTTPS URL. The PFX must contain a private key, be currently valid, and must not grant permissions to group or other users (0600 is the normal setting). The script checks the certificate thumbprint if -CertificateThumbprint is supplied or stored in the selected profile, and warns when the certificate expires in fewer than 30 days.

Profiles are filtered by exact -ProfileName, -Tenant, and -SiteUrl values. The script requires exactly one match. If a profile stores a relative PFX path, it is resolved relative to the profile file's directory. A Windows-style profile containing only a certificate thumbprint is not sufficient on Linux: provide a PFX through -CertificateFilePath or add a certificateFilePath value to that profile.

Unattended connections

For automation, pass a SecureString password from a secret vault:

./o365-connect-pnp-cert-linux.ps1 `
  -UseCertificateAuth `
  -Tenant contoso.onmicrosoft.com `
  -SiteUrl https://contoso.sharepoint.com `
  -AppId 11111111-2222-3333-4444-555555555555 `
  -CertificateFilePath /home/admin/auth.pfx `
  -CertificatePassword $vaultPassword `
  -noprompt `
  -noupdate

Alternatively, name an environment variable populated by the scheduler or secret manager:

./o365-connect-pnp-cert-linux.ps1 `
  -UseCertificateAuth `
  -ProfileName Contoso `
  -CertificatePasswordEnvironmentVariable PNP_PFX_PASSWORD `
  -Headless `
  -noupdate

-noprompt is an alias-compatible spelling of -Headless. In this mode, the relevant password must be passed as a SecureString or provided through the named process environment variable, and required modules must already be installed. Passwords are not saved in profiles or printed. Environment variables can be read by processes running as the same user, so a secret vault and a SecureString are preferable where practical.

-noupdate skips the PnP.PowerShell Gallery version check. Without it, the script checks for a newer version when interactive; installing an update requires confirmation. Update-check failures are warnings, not connection success guarantees. Headless mode skips update checks.

The script connects in the current PowerShell process and leaves the PnP connection active when it completes successfully. Run it in the same PowerShell session or job that will execute PnP cmdlets; a separate pwsh -File process exits when the script finishes, ending that process's connection. If previously loaded module assemblies conflict with the required version, use a fresh pwsh session.

Files, profiles, and permissions

By default, certificate files and transcript logs use:

  • $XDG_DATA_HOME/ciaops/pnp when XDG_DATA_HOME is set to an absolute path; otherwise ~/.local/share/ciaops/pnp.

The profile map defaults to:

  • $XDG_CONFIG_HOME/ciaops/pnp/o365-pnp-cert-auth.json when XDG_CONFIG_HOME is set to an absolute path; otherwise ~/.config/ciaops/pnp/o365-pnp-cert-auth.json.

The profile file can be a JSON array or an object with a profiles array. Each profile records a name, tenant, site URL, app ID, certificate thumbprint, and certificate file path. Passwords are never included. -CertificateMapPath selects a different profile map; custom output and profile directories must be dedicated to this script because it restricts their permissions.

The script sets its storage directories to owner-only permissions (0700) and creates private files with owner read/write permissions (0600), independent of the process umask. It rejects symbolic links in storage paths and rejects a symbolic-link PFX. A PFX with any group/other permissions is refused; correct an existing file with, for example:

chmod 600 -- /home/admin/auth.pfx

-enableLog writes a uniquely named transcript under the private certificate data directory. Provisioning transcripts may include short-lived device codes; protect and remove logs according to your security and retention policies.

Parameter reference

Parameter Description
-GenerateLocalCertificate Generate the certificate files.
-UseCertificateAuth Load a PFX and connect to SharePoint Online.
-ProvisionEntraApp During generation, provision the Entra app and save a profile. Requires -Tenant, -SiteUrl, and interactive sign-in.
-Tenant Tenant ID or domain for provisioning/connection and profile filtering.
-SiteUrl Absolute HTTPS SharePoint site URL; required for provisioning and explicit connection.
-AppId Entra application (client) ID for an explicit connection.
-CertificateFilePath PFX path; overrides the path from a profile.
-CertificatePassword PFX password as a SecureString for connection.
-CertificatePasswordEnvironmentVariable Process environment variable name containing the password, used only when the relevant secure-string parameter is omitted.
-CertificateThumbprint Optional expected thumbprint to verify against the PFX.
-CertificateMapPath JSON profile map path.
-ProfileName Exact profile name to select; during provisioning, also overrides the saved profile name.
-AppDisplayName App display name for provisioning; defaults to -GeneratedCertSubject.
-SetupClientId Optional public client ID for Microsoft Graph device sign-in.
-noprompt / -Headless Disable prompts; requires passwords and modules to be prepared, and skips update checks.
-noupdate Skip the PnP.PowerShell Gallery version check.
-enableLog Save a transcript in the private certificate data directory.

Troubleshooting

Symptom Resolution
“Specify exactly one…” Use exactly one of -GenerateLocalCertificate or -UseCertificateAuth.
Headless mode requires a password Pass the appropriate password as a SecureString, or configure the named environment variable in the process before running.
Required module is missing in headless mode Install the required module for the current user before running; headless mode does not install modules.
A module is loaded below the required version Start a fresh pwsh session after installing the required version.
No unique matching profile Specify -ProfileName, refine the tenant/site filters, or supply all four explicit connection values.
PFX permissions are rejected Remove group/other access (for example, chmod 600 -- /path/to/file.pfx) and retry.
PFX is rejected as a certificate without a private key Supply the encrypted .pfx, not the public .cer.
Expected thumbprint does not match Verify that the PFX and profile/parameter thumbprint refer to the same certificate.
Connection fails soon after provisioning Allow Entra permission replication time and retry from a fresh PowerShell session.

For cmdlet details, see the Connect-PnPOnline documentation.

Clone this wiki locally