Skip to content

WellKnownMixin

Can be used to define well-known endpoints that are exposed on the root of the instance. These are always redirects and generally are available without authentication. Well-Known endpoints are a common discovery mechanism for web services and were originally defined in RFC 5785. IANA runs a registry with commonly acknowledged endpoints but generally one can define their own (this is not recommended by the RFC and technically one needs to register a name to be considered well-known).

The Mixin does not validate the endpoint names and does not enforce acceptable schemes or authorisation as these details depend on the service being advertised. The RFC is very liberal about these details.

Warning

The index of well-known names and endpoints is always available without authentication. The advertised endpoints themselves are not required to be available without authentication but it is a common pattern. InvenTree.permissions.auth_exempt can be used as a decorator to achieve that. Exposing endpoints without authentication is a security risk and should be done with care and only for selected endpoints.

Collection of endpoints is done by implementing the get_well_known_urls collector method which returns a list of tuples of the form (name, url) where name is the well-known name and url is the URL to redirect to. The URL might be lazy but must be resolvable to a string - which will be treated as a url.

from django.urls import path, reverse_lazy

class MyWellKnownPlugin(WellKnownMixin, InvenTreePlugin):

    NAME = "WellKnownMixin"

    def get_well_known_urls(
        self, request = None
    ):
        """Return well-known entries."""
        return [('abc-method', reverse_lazy('url-pattern-name'))]

The defined well-known URLs get exposed under /.well-known/ so above example would make available a redirect to the view name 'url-pattern-name' at /.well-known/abc-method/ and list the method in the unauthenticated, public /.well-known/ index.

Security considerations

The request object is passed to the collector method when it is available (during some operations like initialisation that is not the case) so that the plugin could potentially decide to hide itself on the index from unauthenticated users or based on other request parameters. The urlpattern might still be registered, that needs to be considered when implementing the views authentication response.

Due to (D)DOS concerns it is recommended to keep the collector function as lightweight as possible and especially to avoid database trips or other expensive operations. Default rate limits do not apply to the index as this is outside of the API surface!

Sample Plugin

The following real world example demonstrates how to use the WellKnownMixin class to provide well-known endpoints. This plugin is shipped as part of InvenTree and is mandatory. It shows how a single plugin can define and expose a well-known endpoint.

Plugin which provides built-in well-known URLs.

Source code in src/backend/InvenTree/plugin/builtin/integration/core_wellknown.py
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
class InvenTreeWellKnown(WellKnownMixin, UrlsMixin, InvenTreePlugin):
    """Plugin which provides built-in well-known URLs."""

    NAME = 'InvenTreeWellKnown'
    SLUG = 'inventree-well-known'
    TITLE = _('InvenTree Well-Known URLs')
    DESCRIPTION = _('Built-in well-known URLs for InvenTree')
    AUTHOR = _('InvenTree contributors')
    VERSION = '1.0.0'

    def get_well_known_urls(
        self, request: 'HttpRequest | None' = None
    ) -> list[tuple[str, str]]:
        """Return all built-in well-known entries."""
        data = []

        # See https://www.w3.org/TR/passkey-endpoints/
        data.append(('passkey-endpoints', reverse_lazy(f'plugin:{self.slug}:passkey')))

        # Check if OIDC is enabled, and if so, add the relevant entries
        try:
            if flag_enabled('OIDC', request=request):
                data.append((
                    'openid-configuration',
                    str(reverse_lazy('oauth2_provider:oidc-connect-discovery-info')),
                ))
        except Exception:  # pragma: no cover
            # If the flag is not evaluated successfully, we can ignore it
            pass

        # change password to help pwd managers - see https://adamj.eu/tech/2026/09/16/django-change-password-url/
        data.append((
            'change-password',
            reverse_lazy(f'plugin:{self.slug}:change-password'),
        ))
        # dead url (for change-password)
        data.append((
            'resource-that-should-not-exist-whose-status-code-should-not-be-200',
            reverse_lazy(f'plugin:{self.slug}:dead'),
        ))

        return data

    @auth_exempt
    def view_passkey(self, request, *args, **kwargs):
        """Return the passkey well-known entry."""
        passkey_web = request.build_absolute_uri(
            InvenTree.helpers.pui_url('/settings/user/security')
        )
        return JsonResponse({'enroll': passkey_web, 'manage': passkey_web})

    @auth_exempt
    def view_change_password(self, request, *args, **kwargs):
        """Redirect to the change-password web page."""
        return redirect(
            request.build_absolute_uri(InvenTree.helpers.pui_url('/change-password'))
        )

    @auth_exempt
    def view_dead(self, request, *args, **kwargs):
        """Return a 404 for the dead well-known entry."""
        return JsonResponse({'error': 'Not found'}, status=404)

    def setup_urls(self):
        """Urls that are exposed by this plugin."""
        return [
            path('passkey/', self.view_passkey, name='passkey'),
            path('change-password', self.view_change_password, name='change-password'),
            path('dead', self.view_dead, name='dead'),
        ]