Skip to content


Switch branches/tags

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time


PrivateAuth is an extension to the IndieAuth protocol. It's intended to allow authentication to small applications with a limited audience; for example, a private media server, a home automation system, or a personal blog.

It tries to be as compatible as possible with IndieAuth from an endpoint perspective. A PrivateAuth endpoint should be able to handle logins for both PrivateAuth and IndieAuth clients. That way, a user may reuse an existing IndieAuth endpoint with a PrivateAuth client, or vice-versa.

To a certain degree, this compatibility extends to clients; however, clients that support both IndieAuth and PrivateAuth logins MUST verify the domain of PrivateAuth logins. In other words, they MAY NOT skip the domain check as part of the Authentication code verification section below.


A restricted client is one that wishes to limit the users that can sign into it. A full client is one that allows any user to sign in.

A user's profile data is comprised of the additional fields (name, shortName, and username) specified in the Authentication code verification section below.


The authentication flow is very similar to IndieAuth. You might want to compare with section 5 of the IndieAuth spec.


A restricted client MAY skip the authorization endpoint discovery step. In this case, the restricted client SHOULD provide a configuration mechanism to allow an administrator to set a trusted authorization endpoint.

Clients MAY also provide a configuration mechanism to determine if they should behave in either a restricted or full manner.

Authentication request

When building the authentication request, a restricted client MAY omit the me parameter, and rely on the authorization endpoint to determine the user's profile URL. This breaks compatibility with IndieAuth endpoints, and so should be only done if a developer is certain that their restricted client will only be used with PrivateAuth endpoints.

If an authorization endpoint receives a request without the me parameter, it MUST somehow resolve the user's profile URL. How exactly this happens is dependent on the specific implementation—for example, a user could be prompted to enter their profile URL, or the endpoint could automatically calculate a profile URL based on a username entered by the user.

Authentication response

There are no changes to this section from the IndieAuth specification.

Authentication code verification

If a restricted client chose to omit the me parameter in the initial request, then it is not possible to verify that the returned profile URL's domain is correct. Therefore, this domain check MAY be skipped by restricted clients.

Important: this domain check MAY NOT be skipped in a client that supports both IndieAuth and PrivateAuth logins, as this would be a security flaw. Both IndieAuth clients and PrivateAuth full clients must be able to reject logins from a malicious endpoint—that is, an endpoint that claims to authenticate users for a domain that it does not control.

When making the verification request, the client MUST add the X-PrivateAuth-Version header, with a value of 1. Endpoints that receive valid requests with this header MUST have a JSON response containing fields according to the following table:

Field Status Description Example
me required This has the same meaning as it does in the IndieAuth specification. ""
name optional The user's full name. "Alex Studer"
shortName optional A short version of the user's full name. "Alex"
username required A unique identifier of the user's account at the endpoint. "alex"
permissions required An array of a user's permissions. See the Permissions section below. ["sampleapp:read", ""]

The username MUST be unique between different users on the same endpoint, but MAY be the same between different users on different endpoints. The name and shortName fields do not have any uniqueness requirements.

For compatibility reasons, clients MUST be able to ignore additional fields beyond what is specified here. That is, if a future revision of the specification adds additional fields, existing clients MUST ignore the additions.


PrivateAuth adds the concept of permissions: arbitrary strings associated with a user that can be interpreted by clients. Permissions SHOULD always be in lowercase, and MUST be verified by clients in a case-insensitive manner.


This section is non-normative.

While the specification does not impose requirements on what permission strings look like, the convention is to use the client's name, a colon (:), and a descriptive string of the permission. If some hierarchy is needed in the descriptive string, a period (.) may be used.

For example, a client named "SampleApp" might look for the permissions sampleapp:read, sampleapp:write, and sampleapp:admin. A cloud storage client named "DifferentApp" might have permissions, differentapp:documents.write,, and differentapp:photos.write.

A client SHOULD report an error if it finds a permission with its application name that it does not recognize, to protect against configuration errors. Clients SHOULD NOT depend on permissions that belong to other clients.


This section is non-normative.

The PrivateAuth specification does not include the concept of roles for a user. However, endpoints MAY implement this concept by allowing an administrator to define roles as lists of permissions, and then allow assigning users to those roles.

For example, an administrator could configure their endpoint to have an "Editor" role with permissions of ["sampleapp:read", "sampleapp:write", "", "differentapp:documents.write"]. Then, any users with the "Editor" role assigned would automatically have those permissions added to their overall permissions array.



PrivateAuth is an extension to the IndieAuth protocol.







No releases published


No packages published