diff --git a/.github/workflows/automatic-doc-checks.yml b/.github/workflows/automatic-doc-checks.yml new file mode 100644 index 0000000000..621a6cedf4 --- /dev/null +++ b/.github/workflows/automatic-doc-checks.yml @@ -0,0 +1,18 @@ +name: Main Documentation Checks + +on: + push: + branches: [main] + pull_request: + # Manual trigger + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + documentation-checks: + uses: canonical/documentation-workflows/.github/workflows/documentation-checks.yaml@main + with: + working-directory: "./docs" diff --git a/.wokeignore b/.wokeignore new file mode 120000 index 0000000000..19f3fe4bda --- /dev/null +++ b/.wokeignore @@ -0,0 +1 @@ +docs/.wokeignore \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index efeb5ecf36..21806320da 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,11 +1,13 @@ -# Contributing to authd + +# Contributing to Authd A big welcome and thank you for considering making a contribution to authd and Ubuntu! It’s people like you that help make these products a reality for users in our community. By agreeing to follow these guidelines the contribution process should be easy and effective for everyone involved. This also communicates that you agree to respect the time of the developers working on this project. In return, we will reciprocate that respect by addressing your issues, assessing proposed changes and helping you finalise your pull requests. -These are mostly guidelines, not rules. Use your best judgment and feel free to propose changes to this document in a pull request. +These are mostly guidelines, not rules. Use your best judgement and feel free to propose changes to this document in a pull request. + ## Quicklinks - [Contributing to authd](#contributing-to-authd) @@ -27,9 +29,10 @@ These are mostly guidelines, not rules. Use your best judgment and feel free to - [Contributor License Agreement](#contributor-license-agreement) - [Getting help](#getting-help) + ## Code of conduct -We take our community seriously, holding ourselves and other contributors to high standards of communication. By contributing to this project you agree to uphold the Ubuntu community [Code of Conduct](https://ubuntu.com/community/code-of-conduct). +We take our community seriously, holding ourselves and other contributors to high standards of communication. By contributing to this project you agree to uphold the Ubuntu community [Code of Conduct](https://ubuntu.com/community/ethos/code-of-conduct). ## Getting Started @@ -54,7 +57,7 @@ PRs to our project are always welcome and can be a quick way to get your fix or * Only fix/add the functionality in question **OR** address wide-spread whitespace/style issues, not both. * Add unit or integration tests for fixed or changed functionality. * Address a single concern in the least possible number of changed lines. -* Include documentation in the repo or on our [docs site](https://github.com/canonical/authd/wiki). +* Include documentation in the repo or on our [docs site](https://github.com/ubuntu/authd/wiki). * Be accompanied by a complete Pull Request template (loaded automatically when a PR is created). For changes that address core functionality or that would require breaking changes (e.g. a major release), it's best to open an Issue to discuss your proposal first. This is not required but can save time when creating and reviewing changes. @@ -115,7 +118,7 @@ Then build the Debian package: debuild --prepend-path=${HOME}/.cargo/bin ``` -The debian packages are available in the parent directory. +The Debian packages are available in the parent directory. #### Building authd only @@ -152,7 +155,7 @@ This last command will produce two libraries (`./pam/pam_authd.so` and `./pam/go These modules must be copied to `/usr/lib/$(gcc -dumpmachine)/security/` while the executable must be copied to `/usr/libexec/authd-pam`. For further information about the PAM module architecture and testing see the -[PAM Hacking](./pam/Hacking.md) page. +[PAM Hacking](https://github.com/ubuntu/authd/blob/main/pam/Hacking.md) page. #### Building the NSS module only @@ -196,8 +199,10 @@ You only need to sign this once and if you have previously signed the agreement An automated test is executed on PRs to check if this agreement has been accepted. -This project is covered by [THIS LICENSE](LICENSE). + + ## Getting help Join us in the [Ubuntu Community](https://discourse.ubuntu.com/c/desktop/8) and post your question there with a descriptive tag. + diff --git a/docs/.custom_wordlist.txt b/docs/.custom_wordlist.txt new file mode 100644 index 0000000000..77023debae --- /dev/null +++ b/docs/.custom_wordlist.txt @@ -0,0 +1,36 @@ +amd +auth +authd +biometric +DBus +entra +GDM +GIDs +gRPC +github +grpc +https +io +msentraid +NFS +nss +OIDC +OpenID +ppa +PR +protoc +PRs +repo +smartcard +sshd +styleguide +sudo +TPM +ubuntu +UID +UIDs +unix +vendorize +vhs +webview +whitespace diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 0000000000..468749d851 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,17 @@ + +# Starter pack rules start here +/*env*/ +.sphinx/venv/ +.sphinx/warnings.txt +.sphinx/.wordlist.dic +.sphinx/.doctrees/ +.sphinx/node_modules/ +package*.json +_build +.DS_Store +__pycache__ +.idea/ +.vscode/ +.sphinx/styles/* +.sphinx/vale.ini +sp-docs/_build \ No newline at end of file diff --git a/docs/.readthedocs.yaml b/docs/.readthedocs.yaml new file mode 100644 index 0000000000..f170b00667 --- /dev/null +++ b/docs/.readthedocs.yaml @@ -0,0 +1,30 @@ +# .readthedocs.yaml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the version of Python and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.11" + jobs: + pre_install: + - git fetch --unshallow || true + +# Build documentation in the docs/ directory with Sphinx +sphinx: + builder: dirhtml + configuration: docs/conf.py + fail_on_warning: true + +# If using Sphinx, optionally build your docs in additional formats such as PDF +formats: + - pdf + +# Optionally declare the Python requirements required to build your docs +python: + install: + - requirements: docs/.sphinx/requirements.txt diff --git a/docs/.sphinx/.markdownlint.json b/docs/.sphinx/.markdownlint.json new file mode 100644 index 0000000000..8aafaf6ddb --- /dev/null +++ b/docs/.sphinx/.markdownlint.json @@ -0,0 +1,16 @@ +{ + "default": false, + "MD003": { "style": "atx" }, + "MD013": { "code_blocks": false, "tables": false, "stern": true, "line_length": 150}, + "MD014": true, + "MD018": true, + "MD022": true, + "MD023": true, + "MD026": { "punctuation": ".,;。,;"}, + "MD031": { "list_items": false}, + "MD032": true, + "MD035": true, + "MD042": true, + "MD045": true, + "MD052": true +} \ No newline at end of file diff --git a/docs/.sphinx/.wordlist.txt b/docs/.sphinx/.wordlist.txt new file mode 100644 index 0000000000..be5021a1f6 --- /dev/null +++ b/docs/.sphinx/.wordlist.txt @@ -0,0 +1,64 @@ +ACME +ACME's +addons +AGPLv +API +APIs +balancer +Charmhub +CLI +DCO +Diátaxis +Dqlite +dropdown +EBS +EKS +enablement +favicon +Furo +Git +GitHub +Grafana +IAM +installable +JSON +Juju +Kubeflow +Kubernetes +Launchpad +linter +LTS +LXD +Makefile +Makefiles +Matrix +Mattermost +MicroCeph +MicroCloud +MicroOVN +MyST +namespace +namespaces +NodePort +Numbat +observability +OEM +OLM +Permalink +pre +Quickstart +ReadMe +reST +reStructuredText +roadmap +RTD +subdirectories +subfolders +subtree +TODO +Ubuntu +UI +UUID +VM +webhook +YAML diff --git a/docs/.sphinx/_static/css/pdf.css b/docs/.sphinx/_static/css/pdf.css new file mode 100644 index 0000000000..f9e28dd2df --- /dev/null +++ b/docs/.sphinx/_static/css/pdf.css @@ -0,0 +1,15 @@ +/* Only relevant for specific PDF generation issues */ + +.rubric>.hclass2 { + display: block; + font-size: 2em; + border-radius: .5rem; + font-weight: 300; + line-height: 1.25; + margin-top: 1.75rem; + margin-right: -0.5rem; + margin-bottom: 0.5rem; + margin-left: -0.5rem; + padding-left: .5rem; + padding-right: .5rem; +} \ No newline at end of file diff --git a/docs/.sphinx/_static/favicon.png b/docs/.sphinx/_static/favicon.png new file mode 100644 index 0000000000..7f175e4617 Binary files /dev/null and b/docs/.sphinx/_static/favicon.png differ diff --git a/docs/.sphinx/_static/tag.png b/docs/.sphinx/_static/tag.png new file mode 100644 index 0000000000..f6f6e5aa4b Binary files /dev/null and b/docs/.sphinx/_static/tag.png differ diff --git a/docs/.sphinx/_templates/header.html b/docs/.sphinx/_templates/header.html new file mode 100644 index 0000000000..5e3e776d26 --- /dev/null +++ b/docs/.sphinx/_templates/header.html @@ -0,0 +1,54 @@ + diff --git a/docs/.sphinx/fonts/LICENCE.txt b/docs/.sphinx/fonts/LICENCE.txt new file mode 100644 index 0000000000..ae78a8f94e --- /dev/null +++ b/docs/.sphinx/fonts/LICENCE.txt @@ -0,0 +1,96 @@ +------------------------------- +UBUNTU FONT LICENCE Version 1.0 +------------------------------- + +PREAMBLE +This licence allows the licensed fonts to be used, studied, modified and +redistributed freely. The fonts, including any derivative works, can be +bundled, embedded, and redistributed provided the terms of this licence +are met. The fonts and derivatives, however, cannot be released under +any other licence. The requirement for fonts to remain under this +licence does not require any document created using the fonts or their +derivatives to be published under this licence, as long as the primary +purpose of the document is not to be a vehicle for the distribution of +the fonts. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this licence and clearly marked as such. This may +include source files, build scripts and documentation. + +"Original Version" refers to the collection of Font Software components +as received under this licence. + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to +a new environment. + +"Copyright Holder(s)" refers to all individuals and companies who have a +copyright ownership of the Font Software. + +"Substantially Changed" refers to Modified Versions which can be easily +identified as dissimilar to the Font Software by users of the Font +Software comparing the Original Version with the Modified Version. + +To "Propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification and with or without charging +a redistribution fee), making available to the public, and in some +countries other activities as well. + +PERMISSION & CONDITIONS +This licence does not grant any rights under trademark law and all such +rights are reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of the Font Software, to propagate the Font Software, subject to +the below conditions: + +1) Each copy of the Font Software must contain the above copyright +notice and this licence. These can be included either as stand-alone +text files, human-readable headers or in the appropriate machine- +readable metadata fields within text or binary files as long as those +fields can be easily viewed by the user. + +2) The font name complies with the following: +(a) The Original Version must retain its name, unmodified. +(b) Modified Versions which are Substantially Changed must be renamed to +avoid use of the name of the Original Version or similar names entirely. +(c) Modified Versions which are not Substantially Changed must be +renamed to both (i) retain the name of the Original Version and (ii) add +additional naming elements to distinguish the Modified Version from the +Original Version. The name of such Modified Versions must be the name of +the Original Version, with "derivative X" where X represents the name of +the new work, appended to that name. + +3) The name(s) of the Copyright Holder(s) and any contributor to the +Font Software shall not be used to promote, endorse or advertise any +Modified Version, except (i) as required by this licence, (ii) to +acknowledge the contribution(s) of the Copyright Holder(s) or (iii) with +their explicit written permission. + +4) The Font Software, modified or unmodified, in part or in whole, must +be distributed entirely under this licence, and must not be distributed +under any other licence. The requirement for fonts to remain under this +licence does not affect any document created using the Font Software, +except any version of the Font Software extracted from a document +created using the Font Software may only be distributed under this +licence. + +TERMINATION +This licence becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF +COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER +DEALINGS IN THE FONT SOFTWARE. diff --git a/docs/.sphinx/fonts/Ubuntu-B.ttf b/docs/.sphinx/fonts/Ubuntu-B.ttf new file mode 100644 index 0000000000..b173da2741 Binary files /dev/null and b/docs/.sphinx/fonts/Ubuntu-B.ttf differ diff --git a/docs/.sphinx/fonts/Ubuntu-R.ttf b/docs/.sphinx/fonts/Ubuntu-R.ttf new file mode 100644 index 0000000000..d748728a20 Binary files /dev/null and b/docs/.sphinx/fonts/Ubuntu-R.ttf differ diff --git a/docs/.sphinx/fonts/Ubuntu-RI.ttf b/docs/.sphinx/fonts/Ubuntu-RI.ttf new file mode 100644 index 0000000000..4f2d2bc7cb Binary files /dev/null and b/docs/.sphinx/fonts/Ubuntu-RI.ttf differ diff --git a/docs/.sphinx/fonts/UbuntuMono-B.ttf b/docs/.sphinx/fonts/UbuntuMono-B.ttf new file mode 100644 index 0000000000..7bd6665765 Binary files /dev/null and b/docs/.sphinx/fonts/UbuntuMono-B.ttf differ diff --git a/docs/.sphinx/fonts/UbuntuMono-R.ttf b/docs/.sphinx/fonts/UbuntuMono-R.ttf new file mode 100644 index 0000000000..fdd309d716 Binary files /dev/null and b/docs/.sphinx/fonts/UbuntuMono-R.ttf differ diff --git a/docs/.sphinx/fonts/UbuntuMono-RI.ttf b/docs/.sphinx/fonts/UbuntuMono-RI.ttf new file mode 100644 index 0000000000..18f81a2925 Binary files /dev/null and b/docs/.sphinx/fonts/UbuntuMono-RI.ttf differ diff --git a/docs/.sphinx/get_vale_conf.py b/docs/.sphinx/get_vale_conf.py new file mode 100644 index 0000000000..9ee2d0b5f6 --- /dev/null +++ b/docs/.sphinx/get_vale_conf.py @@ -0,0 +1,53 @@ +#! /usr/bin/env python + +import requests +import os + +DIR = os.getcwd() + + +def main(): + if os.path.exists(f"{DIR}/.sphinx/styles/Canonical"): + print("Vale directory exists") + else: + os.makedirs(f"{DIR}/.sphinx/styles/Canonical") + + url = ( + "https://api.github.com/repos/canonical/praecepta/" + + "contents/styles/Canonical" + ) + r = requests.get(url) + for item in r.json(): + download = requests.get(item["download_url"]) + file = open(".sphinx/styles/Canonical/" + item["name"], "w") + file.write(download.text) + file.close() + + if os.path.exists(f"{DIR}/.sphinx/styles/config/vocabularies/Canonical"): + print("Vocab directory exists") + else: + os.makedirs(f"{DIR}/.sphinx/styles/config/vocabularies/Canonical") + + url = ( + "https://api.github.com/repos/canonical/praecepta/" + + "contents/styles/config/vocabularies/Canonical" + ) + r = requests.get(url) + for item in r.json(): + download = requests.get(item["download_url"]) + file = open( + ".sphinx/styles/config/vocabularies/Canonical/" + item["name"], + "w" + ) + file.write(download.text) + file.close() + config = requests.get( + "https://raw.githubusercontent.com/canonical/praecepta/main/vale.ini" + ) + file = open(".sphinx/vale.ini", "w") + file.write(config.text) + file.close() + + +if __name__ == "__main__": + main() diff --git a/docs/.sphinx/images/Canonical-logo-4x.png b/docs/.sphinx/images/Canonical-logo-4x.png new file mode 100644 index 0000000000..fd75696eb5 Binary files /dev/null and b/docs/.sphinx/images/Canonical-logo-4x.png differ diff --git a/docs/.sphinx/images/front-page-light.pdf b/docs/.sphinx/images/front-page-light.pdf new file mode 100644 index 0000000000..bb68cdf8f5 Binary files /dev/null and b/docs/.sphinx/images/front-page-light.pdf differ diff --git a/docs/.sphinx/images/normal-page-footer.pdf b/docs/.sphinx/images/normal-page-footer.pdf new file mode 100644 index 0000000000..dfd73cbc7e Binary files /dev/null and b/docs/.sphinx/images/normal-page-footer.pdf differ diff --git a/docs/.sphinx/latex_elements_template.txt b/docs/.sphinx/latex_elements_template.txt new file mode 100644 index 0000000000..322412c7de --- /dev/null +++ b/docs/.sphinx/latex_elements_template.txt @@ -0,0 +1,119 @@ +{ + 'papersize': 'a4paper', + 'pointsize': '11pt', + 'fncychap': '', + 'preamble': r''' +%\usepackage{charter} +%\usepackage[defaultsans]{lato} +%\usepackage{inconsolata} +\setmainfont[UprightFont = *-R, BoldFont = *-B, ItalicFont=*-RI, Extension = .ttf]{Ubuntu} +\setmonofont[UprightFont = *-R, BoldFont = *-B, ItalicFont=*-RI, Extension = .ttf]{UbuntuMono} +\usepackage[most]{tcolorbox} +\tcbuselibrary{breakable} +\usepackage{lastpage} +\usepackage{tabto} +\usepackage{ifthen} +\usepackage{etoolbox} +\usepackage{fancyhdr} +\usepackage{graphicx} +\usepackage{titlesec} +\usepackage{fontspec} +\usepackage{tikz} +\usepackage{changepage} +\usepackage{array} +\usepackage{tabularx} +\definecolor{yellowgreen}{RGB}{154, 205, 50} +\definecolor{title}{RGB}{76, 17, 48} +\definecolor{subtitle}{RGB}{116, 27, 71} +\definecolor{label}{RGB}{119, 41, 100} +\definecolor{copyright}{RGB}{174, 167, 159} +\makeatletter +\def\tcb@finalize@environment{% + \color{.}% hack for xelatex + \tcb@layer@dec% +} +\makeatother +\newenvironment{sphinxclassprompt}{\color{yellowgreen}\setmonofont[Color = 9ACD32, UprightFont = *-R, Extension = .ttf]{UbuntuMono}}{} +\tcbset{enhanced jigsaw, colback=black, fontupper=\color{white}} +\newtcolorbox{termbox}{use color stack, breakable, colupper=white, halign=flush left} +\newenvironment{sphinxclassterminal}{\setmonofont[Color = white, UprightFont = *-R, Extension = .ttf]{UbuntuMono}\sphinxsetup{VerbatimColor={black}}\begin{termbox}}{\end{termbox}} +\newcommand{\dimtorightedge}{% + \dimexpr\paperwidth-1in-\hoffset-\oddsidemargin\relax} +\newcommand{\dimtotop}{% + \dimexpr\height-1in-\voffset-\topmargin-\headheight-\headsep\relax} +\newtoggle{tpage} +\AtBeginEnvironment{titlepage}{\global\toggletrue{tpage}} +\fancypagestyle{plain}{ + \fancyhf{} + \fancyfoot[R]{\thepage\ of \pageref*{LastPage}} + \renewcommand{\headrulewidth}{0pt} + \renewcommand{\footrulewidth}{0pt} +} +\fancypagestyle{normal}{ + \fancyhf{} + \fancyfoot[R]{\thepage\ of \pageref*{LastPage}} + \renewcommand{\headrulewidth}{0pt} + \renewcommand{\footrulewidth}{0pt} +} +\fancypagestyle{titlepage}{% + \fancyhf{} + \fancyfoot[L]{\footnotesize \textcolor{copyright}{© 2024 Canonical Ltd. All rights reserved.}} +} +\newcommand\sphinxbackoftitlepage{\thispagestyle{titlepage}} +\titleformat{\chapter}[block]{\Huge \color{title} \bfseries\filright}{\thechapter .}{1.5ex}{} +\titlespacing{\chapter}{0pt}{0pt}{0pt} +\titleformat{\section}[block]{\huge \bfseries\filright}{\thesection .}{1.5ex}{} +\titlespacing{\section}{0pt}{0pt}{0pt} +\titleformat{\subsection}[block]{\Large \bfseries\filright}{\thesubsection .}{1.5ex}{} +\titlespacing{\subsection}{0pt}{0pt}{0pt} +\setcounter{tocdepth}{1} +\renewcommand\pagenumbering[1]{} +''', + 'sphinxsetup': 'verbatimwithframe=false, pre_border-radius=0pt, verbatimvisiblespace=\\phantom{}, verbatimcontinued=\\phantom{}', + 'extraclassoptions': 'openany,oneside', + 'maketitle': r''' +\begin{titlepage} +\begin{flushleft} + \begin{tikzpicture}[remember picture,overlay] + \node[anchor=south east, inner sep=0] at (current page.south east) { + \includegraphics[width=\paperwidth, height=\paperheight]{front-page-light} + }; + \end{tikzpicture} +\end{flushleft} + +\vspace*{3cm} + +\begin{adjustwidth}{8cm}{0pt} +\begin{flushleft} + \huge \textcolor{black}{\textbf{}{\raggedright{$PROJECT}}} +\end{flushleft} +\end{adjustwidth} + +\vfill + +\begin{adjustwidth}{8cm}{0pt} +\begin{tabularx}{0.5\textwidth}{ l l } + \textcolor{lightgray}{© 2024 Canonical Ltd.} & \hspace{3cm} \\ + \textcolor{lightgray}{All rights reserved.} & \hspace{3cm} \\ + & \hspace{3cm} \\ + & \hspace{3cm} \\ + +\end{tabularx} +\end{adjustwidth} + +\end{titlepage} +\RemoveFromHook{shipout/background} +\AddToHook{shipout/background}{ + \begin{tikzpicture}[remember picture,overlay] + \node[anchor=south west, align=left, inner sep=0] at (current page.south west) { + \includegraphics[width=\paperwidth]{normal-page-footer} + }; + \end{tikzpicture} + \begin{tikzpicture}[remember picture,overlay] + \node[anchor=north east, opacity=0.5, inner sep=35] at (current page.north east) { + \includegraphics[width=4cm]{Canonical-logo-4x} + }; + \end{tikzpicture} + } +''', +} \ No newline at end of file diff --git a/docs/.sphinx/metrics/build_metrics.sh b/docs/.sphinx/metrics/build_metrics.sh new file mode 100755 index 0000000000..bd1ff1cb4c --- /dev/null +++ b/docs/.sphinx/metrics/build_metrics.sh @@ -0,0 +1,15 @@ +#!/bin/bash +# shellcheck disable=all + +links=0 +images=0 + +# count number of links +links=$(find . -type d -path './.sphinx' -prune -o -name '*.html' -exec cat {} + | grep -o " \n" \ + "------------------------------------------------------------- \n" + +%: + $(MAKE) -f Makefile.sp sp-$@ diff --git a/docs/Makefile.sp b/docs/Makefile.sp new file mode 100644 index 0000000000..beaf79dfe8 --- /dev/null +++ b/docs/Makefile.sp @@ -0,0 +1,170 @@ +# Minimal makefile for Sphinx documentation +# +# `Makefile.sp` is from the Sphinx starter pack and should not be +# modified. +# Add your customisation to `Makefile` instead. + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXDIR = .sphinx +SPHINXOPTS ?= -c . -d $(SPHINXDIR)/.doctrees -j auto +SPHINXBUILD ?= $(VENVDIR)/bin/sphinx-build +SOURCEDIR = . +BUILDDIR = _build +VENVDIR = $(SPHINXDIR)/venv +PA11Y = $(SPHINXDIR)/node_modules/pa11y/bin/pa11y.js --config $(SPHINXDIR)/pa11y.json +VENV = $(VENVDIR)/bin/activate +TARGET = * +ALLFILES = *.rst **/*.rst +METRICSDIR = $(SOURCEDIR)/.sphinx/metrics +REQPDFPACKS = latexmk fonts-freefont-otf texlive-latex-recommended texlive-latex-extra texlive-fonts-recommended texlive-font-utils texlive-lang-cjk texlive-xetex plantuml xindy tex-gyre dvipng +CONFIRM_SUDO ?= N + +.PHONY: sp-full-help sp-woke-install sp-spellcheck-install sp-pa11y-install sp-install sp-run sp-html \ + sp-epub sp-serve sp-clean sp-clean-doc sp-spelling sp-spellcheck sp-linkcheck sp-woke \ + sp-allmetrics sp-pa11y sp-pdf-prep-force sp-pdf-prep sp-pdf Makefile.sp sp-vale sp-bash + +sp-full-help: $(VENVDIR) + @. $(VENV); $(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + @echo "\n\033[1;31mNOTE: This help texts shows unsupported targets!\033[0m" + @echo "Run 'make help' to see supported targets." + +# If requirements are updated, venv should be rebuilt and timestamped. +$(VENVDIR): + python3 -c "import venv" || \ + (echo "You must install python3-venv before you can build the documentation."; exit 1) + @echo "... setting up virtualenv" + python3 -m venv $(VENVDIR) + . $(VENV); pip install $(PIPOPTS) --require-virtualenv \ + --upgrade -r $(SPHINXDIR)/requirements.txt \ + --log $(VENVDIR)/pip_install.log + @test ! -f $(VENVDIR)/pip_list.txt || \ + mv $(VENVDIR)/pip_list.txt $(VENVDIR)/pip_list.txt.bak + @. $(VENV); pip list --local --format=freeze > $(VENVDIR)/pip_list.txt + @touch $(VENVDIR) + +sp-woke-install: + @type woke >/dev/null 2>&1 || \ + { \ + echo "Installing system-wide \"woke\" snap..."; \ + confirm_sudo=$(CONFIRM_SUDO); \ + if [ "$$confirm_sudo" != "y" ] && [ "$$confirm_sudo" != "Y" ]; then \ + read -p "This requires sudo privileges. Proceed? [y/N]: " confirm_sudo; \ + fi; \ + if [ "$$confirm_sudo" = "y" ] || [ "$$confirm_sudo" = "Y" ]; then \ + sudo snap install woke; \ + else \ + echo "Installation cancelled."; \ + fi \ + } + +sp-spellcheck-install: + @type aspell >/dev/null 2>&1 || \ + { \ + echo "Installing system-wide \"aspell\" packages..."; \ + confirm_sudo=$(CONFIRM_SUDO); \ + if [ "$$confirm_sudo" != "y" ] && [ "$$confirm_sudo" != "Y" ]; then \ + read -p "This requires sudo privileges. Proceed? [y/N]: " confirm_sudo; \ + fi; \ + if [ "$$confirm_sudo" = "y" ] || [ "$$confirm_sudo" = "Y" ]; then \ + sudo apt-get install aspell aspell-en; \ + else \ + echo "Installation cancelled."; \ + fi \ + } + +sp-pa11y-install: + @type $(PA11Y) >/dev/null 2>&1 || { \ + echo "Installing \"pa11y\" from npm... \n"; \ + mkdir -p $(SPHINXDIR)/node_modules/ ; \ + npm install --prefix $(SPHINXDIR) pa11y; \ + } + +sp-install: $(VENVDIR) + +sp-run: sp-install + . $(VENV); $(VENVDIR)/bin/sphinx-autobuild -b dirhtml "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) + +# Doesn't depend on $(BUILDDIR) to rebuild properly at every run. +sp-html: sp-install + . $(VENV); $(SPHINXBUILD) -W --keep-going -b dirhtml "$(SOURCEDIR)" "$(BUILDDIR)" -w $(SPHINXDIR)/warnings.txt $(SPHINXOPTS) + +sp-epub: sp-install + . $(VENV); $(SPHINXBUILD) -b epub "$(SOURCEDIR)" "$(BUILDDIR)" -w $(SPHINXDIR)/warnings.txt $(SPHINXOPTS) + +sp-serve: sp-html + cd "$(BUILDDIR)"; python3 -m http.server --bind 127.0.0.1 8000 + +sp-clean: sp-clean-doc + @test ! -e "$(VENVDIR)" -o -d "$(VENVDIR)" -a "$(abspath $(VENVDIR))" != "$(VENVDIR)" + rm -rf $(VENVDIR) + rm -rf $(SPHINXDIR)/node_modules/ + rm -rf $(SPHINXDIR)/styles + rm -rf $(SPHINXDIR)/vale.ini + +sp-clean-doc: + git clean -fx "$(BUILDDIR)" + rm -rf $(SPHINXDIR)/.doctrees + +sp-spellcheck: sp-spellcheck-install + . $(VENV) ; python3 -m pyspelling -c $(SPHINXDIR)/spellingcheck.yaml -j $(shell nproc) + +sp-spelling: sp-html sp-spellcheck + +sp-linkcheck: sp-install + . $(VENV) ; $(SPHINXBUILD) -b linkcheck "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) || { grep --color -F "[broken]" "$(BUILDDIR)/output.txt"; exit 1; } + exit 0 + +sp-woke: sp-woke-install + woke $(ALLFILES) --exit-1-on-failure \ + -c https://raw.githubusercontent.com/canonical/Inclusive-naming/main/config.yml + +sp-pa11y: sp-pa11y-install sp-html + find $(BUILDDIR) -name *.html -print0 | xargs -n 1 -0 $(PA11Y) + +sp-vale: sp-install + @. $(VENV); test -d $(SPHINXDIR)/venv/lib/python*/site-packages/vale || pip install vale + @. $(VENV); test -f $(SPHINXDIR)/vale.ini || python3 $(SPHINXDIR)/get_vale_conf.py + @. $(VENV); find $(SPHINXDIR)/venv/lib/python*/site-packages/vale/vale_bin -size 195c -exec vale --config "$(SPHINXDIR)/vale.ini" $(TARGET) > /dev/null \; + @cat $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept.txt > $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept_backup.txt + @cat $(SPHINXDIR)/.wordlist.txt $(SOURCEDIR)/.custom_wordlist.txt >> $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept.txt + @echo "" + @echo "Running Vale against $(TARGET). To change target set TARGET= with make command" + @echo "" + @. $(VENV); vale --config "$(SPHINXDIR)/vale.ini" --glob='*.{md,txt,rst}' $(TARGET) || true + @cat $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept_backup.txt > $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept.txt && rm $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept_backup.txt + +sp-pdf-prep: sp-install + @for packageName in $(REQPDFPACKS); do (dpkg-query -W -f='$${Status}' $$packageName 2>/dev/null | \ + grep -c "ok installed" >/dev/null && echo "Package $$packageName is installed") && continue || \ + (echo "\nPDF generation requires the installation of the following packages: $(REQPDFPACKS)" && \ + echo "" && echo "Run 'sudo make pdf-prep-force' to install these packages" && echo "" && echo \ + "Please be aware these packages will be installed to your system") && exit 1 ; done + +sp-pdf-prep-force: + apt-get update + apt-get upgrade -y + apt-get install --no-install-recommends -y $(REQPDFPACKS) \ + +sp-pdf: sp-pdf-prep + @. $(VENV); sphinx-build -M latexpdf "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) + @rm ./$(BUILDDIR)/latex/front-page-light.pdf || true + @rm ./$(BUILDDIR)/latex/normal-page-footer.pdf || true + @find ./$(BUILDDIR)/latex -name "*.pdf" -exec mv -t ./$(BUILDDIR) {} + + @rm -r $(BUILDDIR)/latex + @echo "\nOutput can be found in ./$(BUILDDIR)\n" + +sp-allmetrics: sp-html + @echo "Recording documentation metrics..." + @echo "Checking for existence of vale..." + . $(VENV) + @. $(VENV); test -d $(SPHINXDIR)/venv/lib/python*/site-packages/vale || pip install vale + @. $(VENV); test -f $(SPHINXDIR)/vale.ini || python3 $(SPHINXDIR)/get_vale_conf.py + @. $(VENV); find $(SPHINXDIR)/venv/lib/python*/site-packages/vale/vale_bin -size 195c -exec vale --config "$(SPHINXDIR)/vale.ini" $(TARGET) > /dev/null \; + @eval '$(METRICSDIR)/source_metrics.sh $(PWD)' + @eval '$(METRICSDIR)/build_metrics.sh $(PWD) $(METRICSDIR)' + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile.sp + . $(VENV); $(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/assets/app-registration.png b/docs/assets/app-registration.png new file mode 100644 index 0000000000..402b3c6b0d Binary files /dev/null and b/docs/assets/app-registration.png differ diff --git a/docs/assets/authd-architecture.png b/docs/assets/authd-architecture.png new file mode 100644 index 0000000000..7c0f9f89e2 Binary files /dev/null and b/docs/assets/authd-architecture.png differ diff --git a/docs/assets/configure-registration.png b/docs/assets/configure-registration.png new file mode 100644 index 0000000000..bd1cce3bc4 Binary files /dev/null and b/docs/assets/configure-registration.png differ diff --git a/docs/assets/gdm-groups.png b/docs/assets/gdm-groups.png new file mode 100644 index 0000000000..3999334c61 Binary files /dev/null and b/docs/assets/gdm-groups.png differ diff --git a/docs/assets/gdm-pass.png b/docs/assets/gdm-pass.png new file mode 100644 index 0000000000..df5d4fa4a8 Binary files /dev/null and b/docs/assets/gdm-pass.png differ diff --git a/docs/assets/gdm-qr.png b/docs/assets/gdm-qr.png new file mode 100644 index 0000000000..02c3ad7dd9 Binary files /dev/null and b/docs/assets/gdm-qr.png differ diff --git a/docs/assets/gdm-select-broker.png b/docs/assets/gdm-select-broker.png new file mode 100644 index 0000000000..dc6950e710 Binary files /dev/null and b/docs/assets/gdm-select-broker.png differ diff --git a/docs/assets/graph-permissions.png b/docs/assets/graph-permissions.png new file mode 100644 index 0000000000..3306b82fae Binary files /dev/null and b/docs/assets/graph-permissions.png differ diff --git a/docs/assets/new-registration.png b/docs/assets/new-registration.png new file mode 100644 index 0000000000..d71ac00579 Binary files /dev/null and b/docs/assets/new-registration.png differ diff --git a/docs/assets/ssh-qr.png b/docs/assets/ssh-qr.png new file mode 100644 index 0000000000..21e1a05cfa Binary files /dev/null and b/docs/assets/ssh-qr.png differ diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000000..1f938d9de1 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,318 @@ +import datetime +import ast + +# Configuration for the Sphinx documentation builder. +# All configuration specific to your project should be done in this file. +# +# If you're new to Sphinx and don't want any advanced or custom features, +# just go through the items marked 'TODO'. +# +# A complete list of built-in Sphinx configuration values: +# https://www.sphinx-doc.org/en/master/usage/configuration.html +# +# Our starter pack uses the custom Canonical Sphinx extension +# to keep all documentation based on it consistent and on brand: +# https://github.com/canonical/canonical-sphinx + + +####################### +# Project information # +####################### + +# Project name +# +# TODO: Update with the official name of your project or product + +project = "Authd" +author = "Canonical Ltd." + + +# Sidebar documentation title; best kept reasonably short +# +# TODO: To include a version number, add it here (hardcoded or automated). +# +# TODO: To disable the title, set to an empty string. + +html_title = project + " documentation" + + +# Copyright string; shown at the bottom of the page +# +# Now, the starter pack uses CC-BY-SA as the license +# and the current year as the copyright year. +# +# TODO: If your docs need another license, specify it instead of 'CC-BY-SA'. +# +# TODO: If your documentation is a part of the code repository of your project, +# it inherits the code license instead; specify it instead of 'CC-BY-SA'. +# +# NOTE: For static works, it is common to provide the first publication year. +# Another option is to provide both the first year of publication +# and the current year, especially for docs that frequently change, +# e.g. 2022–2023 (note the en-dash). +# +# A way to check a repo's creation date is to get a classic GitHub token +# with 'repo' permissions; see https://github.com/settings/tokens +# Next, use 'curl' and 'jq' to extract the date from the API's output: +# +# curl -H 'Authorization: token ' \ +# -H 'Accept: application/vnd.github.v3.raw' \ +# https://api.github.com/repos/canonical/ | jq '.created_at' + +copyright = "%s CC-BY-SA, %s" % (datetime.date.today().year, author) + + +# Documentation website URL +# +# TODO: Update with the official URL of your docs or leave empty if unsure. +# +# NOTE: The Open Graph Protocol (OGP) enhances page display in a social graph +# and is used by social media platforms; see https://ogp.me/ + +ogp_site_url = "https://canonical-starter-pack.readthedocs-hosted.com/" + + +# Preview name of the documentation website +# +# TODO: To use a different name for the project in previews, update as needed. + +ogp_site_name = project + + +# Preview image URL +# +# TODO: To customise the preview image, update as needed. + +ogp_image = \ + "https://assets.ubuntu.com/v1/253da317-image-document-ubuntudocs.svg" + + +# Product favicon; shown in bookmarks, browser tabs, etc. + +# TODO: To customise the favicon, uncomment and update as needed. + +# html_favicon = '.sphinx/_static/favicon.png' + + +# Dictionary of values to pass into the Sphinx context for all pages: +# https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-html_context + +html_context = { + # Product page URL; can be different from product docs URL + # + # TODO: Change to your product website URL, + # dropping the 'https://' prefix, e.g. 'ubuntu.com/lxd'. + # + # TODO: If there's no such website, + # remove the {{ product_page }} link from the page header template + # (usually .sphinx/_templates/header.html; also, see README.rst). + "product_page": "documentation.ubuntu.com", + # Product tag image; the orange part of your logo, shown in the page header + # + # TODO: To add a tag image, uncomment and update as needed. + # 'product_tag': '_static/tag.png', + # Your Discourse instance URL + # + # TODO: Change to your Discourse instance URL or leave empty. + # + # NOTE: If set, adding ':discourse: 123' to an .rst file + # will add a link to Discourse topic 123 at the bottom of the page. + "discourse": "", + # Your Mattermost channel URL + # + # TODO: Change to your Mattermost channel URL or leave empty. + "mattermost": + "", + # Your Matrix channel URL + # + # TODO: Change to your Matrix channel URL or leave empty. + "matrix": "", + # Your documentation GitHub repository URL + # + # TODO: Change to your documentation GitHub repository URL or leave empty. + # + # NOTE: If set, links for viewing the documentation source files + # and creating GitHub issues are added at the bottom of each page. + "github_url": "https://github.com/ubuntu/authd", + # Docs branch in the repo; used in links for viewing the source files + # + # TODO: To customise the branch, uncomment and update as needed. + # 'github_version': 'main', + # Docs location in the repo; used in links for viewing the source files + # + # TODO: To customise the directory, uncomment and update as needed. + "github_folder": "/docs/", + + # TODO: To enable or disable the Previous / Next buttons at the bottom of pages + # Valid options: none, prev, next, both + # "sequential_nav": "both", +} + +# Project slug; see https://meta.discourse.org/t/what-is-category-slug/87897 +# +# TODO: If your documentation is hosted on https://docs.ubuntu.com/, +# uncomment and update as needed. + +# slug = '' + + +# Template and asset locations + +html_static_path = [".sphinx/_static"] +templates_path = [".sphinx/_templates"] + + +############# +# Redirects # +############# + +# To set up redirects: https://documatt.gitlab.io/sphinx-reredirects/usage.html +# For example: 'explanation/old-name.html': '../how-to/prettify.html', + +# To set up redirects in the Read the Docs project dashboard: +# https://docs.readthedocs.io/en/stable/guides/redirects.html + +# NOTE: If undefined, set to None, or empty, +# the sphinx_reredirects extension will be disabled. + +redirects = {} + + +########################### +# Link checker exceptions # +########################### + +# A regex list of URLs that are ignored by 'make linkcheck' +# +# TODO: Remove or adjust the ACME entry after you update the contributing guide + +linkcheck_ignore = [ + "http://127.0.0.1:8000", + "https://github.com/canonical/ACME/*" +] + + +# A regex list of URLs where anchors are ignored by 'make linkcheck' + +linkcheck_anchors_ignore_for_url = [r"https://github\.com/.*"] + + +######################## +# Configuration extras # +######################## + +# Custom MyST syntax extensions; see +# https://myst-parser.readthedocs.io/en/latest/syntax/optional.html +# +# NOTE: By default, the following MyST extensions are enabled: +# substitution, deflist, linkify + +# myst_enable_extensions = set() + + +# Custom Sphinx extensions; see +# https://www.sphinx-doc.org/en/master/usage/extensions/index.html + +# NOTE: The canonical_sphinx extension is required for the starter pack. +# It automatically enables the following extensions: +# - custom-rst-roles +# - myst_parser +# - notfound.extension +# - related-links +# - sphinx_copybutton +# - sphinx_design +# - sphinx_reredirects +# - sphinx_tabs.tabs +# - sphinxcontrib.jquery +# - sphinxext.opengraph +# - terminal-output +# - youtube-links + +extensions = [ + "canonical_sphinx", + "sphinxcontrib.cairosvgconverter", +] + + +# Excludes files or directories from processing + +exclude_patterns = [ + "doc-cheat-sheet*", +] + +# Adds custom CSS files, located under 'html_static_path' + +html_css_files = [ + "css/pdf.css", +] + + +# Adds custom JavaScript files, located under 'html_static_path' + +# html_js_files = [] + + +# Specifies a reST snippet to be appended to each .rst file + +# rst_epilog = """ +# .. include:: /reuse/links.txt +# """ + +# Feedback button at the top; enabled by default +# +# TODO: To disable the button, uncomment this. + +# disable_feedback_button = True + + +# Your manpage URL +# +# TODO: To enable manpage links, uncomment and update as needed. +# +# NOTE: If set, adding ':manpage:' to an .rst file +# adds a link to the corresponding man section at the bottom of the page. + +# manpages_url = f'https://manpages.ubuntu.com/manpages/{codename}/en/' + \ +# f'man{section}/{page}.{section}.html' + + +# Specifies a reST snippet to be prepended to each .rst file +# This defines a :center: role that centers table cell content. +# This defines a :h2: role that styles content for use with PDF generation. + +rst_prolog = """ +.. role:: center + :class: align-center +.. role:: h2 + :class: hclass2 +""" + +# Workaround for https://github.com/canonical/canonical-sphinx/issues/34 + +if "discourse_prefix" not in html_context and "discourse" in html_context: + html_context["discourse_prefix"] = html_context["discourse"] + "/t/" + +##################### +# PDF configuration # +##################### + +latex_additional_files = [ + "./.sphinx/fonts/Ubuntu-B.ttf", + "./.sphinx/fonts/Ubuntu-R.ttf", + "./.sphinx/fonts/Ubuntu-RI.ttf", + "./.sphinx/fonts/UbuntuMono-R.ttf", + "./.sphinx/fonts/UbuntuMono-RI.ttf", + "./.sphinx/fonts/UbuntuMono-B.ttf", + "./.sphinx/images/Canonical-logo-4x.png", + "./.sphinx/images/front-page-light.pdf", + "./.sphinx/images/normal-page-footer.pdf", +] + +latex_engine = "xelatex" +latex_show_pagerefs = True +latex_show_urls = "footnote" + +with open(".sphinx/latex_elements_template.txt", "rt") as file: + latex_config = file.read() + +latex_elements = ast.literal_eval(latex_config.replace("$PROJECT", project)) diff --git a/docs/explanation/authd-architecture.md b/docs/explanation/authd-architecture.md new file mode 100644 index 0000000000..24c4da1561 --- /dev/null +++ b/docs/explanation/authd-architecture.md @@ -0,0 +1,47 @@ +# Authd architecture + +Authd can help organisations ensure secure identity and access management by enabling seamless cloud-based authentication of Ubuntu machines. +Here we explain the architecture of authd and some of its design decisions. +Links are provided at the end to support further reading. + +## Architecture components + +Authd acts as an interface between the host system and external identity providers. +Remote information is cached when authenticating with authd, which improves performance while also facilitating offline access. + +The diagram below illustrates the components of authd and their communication methods: + +![isoflow-export-2024-08-30T13_44_31 725Z](../assets/authd-architecture.png) + +The architecture of authd consists of the following components: + +* The **authentication daemon** (authd): a daemon that runs on the host and manages access to the authentication service. +* An **identity broker**: a trusted component running on the host and serving as an interface with the identity provider. +* The **identity provider**: the remote service that manages digital identities, such as Microsoft Entra ID. +* A **PAM module**: the library that handles the authentication tasks of applications on the system. The authentication tasks that are currently handled by PAM include GDM, login, ssh and sudo. Support for webview is being developed. +* An **NSS module**: a module that queries authd to retrieve user information from the cache. + +```{note} +One or multiple identity brokers and identity providers can be enabled at the same time. +``` + +## Capabilities negotiation + +The platform (whether Ubuntu Desktop, Ubuntu Server, or Ubuntu cloud instance) describes its capabilities and current state, including the availability of a graphical interface, online status, and other general features such as TPM, smartcard, or biometric support. + +The broker, acting as the decision-maker, evaluates its capabilities and current state to select the appropriate workflow. It can also consider specific decision factors, such as temporarily bypassing full MFA or permitting offline cached authentication for a specified duration. + +The broker is a trusted component within the system and serves as the interface with the identity provider. + +## Inter-process communication + +Internal components of authd, such as PAM and NSS modules, communicate over gRPC. The advantage of gRPC is that it delivers high performance and native streaming, with built-in security for efficient and secure communication in distributed systems. + +The communication between authd and the brokers is done over DBus. DBus supports message broadcasting and enables efficient resource sharing. The communication only goes from the authentication daemon to the broker, which responds to requests. The transactions are encrypted, ensuring that communications between the broker and authd are secure. + +## Links + +* [Microsoft Entra fundamentals documentation](https://learn.microsoft.com/en-us/entra/fundamentals/) +* [OpenID Connect (OIDC) on the Microsoft identity platform](https://learn.microsoft.com/en-us/entra/identity-platform/v2-protocols-oidc) +* [What is OpenID Connect and what do you use it for? \- Auth0](https://auth0.com/intro-to-iam/what-is-openid-connect-oidc) +* [What Is OpenID Connect (OIDC)? | Microsoft Security](https://www.microsoft.com/en-us/security/business/security-101/what-is-openid-connect-oidc) diff --git a/docs/explanation/index.md b/docs/explanation/index.md new file mode 100644 index 0000000000..b63a82f222 --- /dev/null +++ b/docs/explanation/index.md @@ -0,0 +1,9 @@ +(explanation)= + +# Explanation + +```{toctree} +:titlesonly: + +Authd architecture +``` diff --git a/docs/howto/configure-authd.md b/docs/howto/configure-authd.md new file mode 100644 index 0000000000..54f5bb7eac --- /dev/null +++ b/docs/howto/configure-authd.md @@ -0,0 +1,76 @@ +# Configure authd + +## Broker discovery + +Create the directory that will contain the declaration files of the broker and copy the one from the Entra ID broker snap package: + +```shell +sudo mkdir -p /etc/authd/brokers.d/ +sudo cp /snap/authd-msentraid/current/conf/authd/msentraid.conf /etc/authd/brokers.d/ +``` + +This file is used to declare the brokers available on the system. Several brokers can be enabled at the same time. + +## Entra ID configuration + +Register a new application in the Microsoft Azure portal. Once the application is registered, note the `Application (client) ID` and the `Directory (tenant) ID` from the `Overview` menu. These IDs are respectively the `` and `` used in the broker configuration file described in this document. + +To register a new application, in Entra, select the menu `Identity > Applications > App registration` + +![image](../assets/app-registration.png) + +Then `New registration` + +![image](../assets/new-registration.png) + +And configure it as follows: + +![image](../assets/configure-registration.png) + +Under `Manage`, in the `API permissions` menu, set the following Microsoft Graph permissions: + +![image](../assets/graph-permissions.png) + +Ensure the API permission type is set to **Delegated** for each permission. + +Finally, as the supported authentication mechanism is the device workflow, you need to allow the public client workflows. Under `Manage`, in the `Authentication` menu, under `Advanced settings`, ensure that `Allow public client flows` is set to **Yes**. + +[The Microsoft documentation](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app) provides detailed instructions for registering an application with the Microsoft identity platform. + +## Broker configuration + +To configure the broker edit the file `/var/snap/authd-msentraid/current/broker.conf`: + +```ini +[oidc] +issuer = https://login.microsoftonline.com//v2.0 +client_id = + +[users] +# The directory where the home directory will be created for new users. +# Existing users will keep their current directory. +# The user home directory will be created in the format of {home_base_dir}/{username} +# home_base_dir = /home + +# The username suffixes that are allowed to login via ssh without existing previously in the system. +# The suffixes must be separated by commas. +# ssh_allowed_suffixes = @example.com,@anotherexample.com +``` + +Replace `` and `` by the issuer ID and client ID retrieved from the MS Entra ID portal. + +When a configuration file is added you have to restart authd: + +```shell +sudo systemctl restart authd +``` + +When the configuration of a broker is updated, you have to restart the broker: + +```shell +sudo snap restart authd-msentraid +``` + +## System configuration + +By default on Ubuntu, the login timeout is 60s. This may be too brief for a device code flow authentication. It can be set to a different value by changing the value of `LOGIN_TIMEOUT` in `/etc/login.defs` diff --git a/docs/howto/contributing.md b/docs/howto/contributing.md new file mode 100644 index 0000000000..962118c0f9 --- /dev/null +++ b/docs/howto/contributing.md @@ -0,0 +1,11 @@ +% Include content from [../CONTRIBUTING.md](../CONTRIBUTING.md) +```{include} ../../CONTRIBUTING.md + :start-after: + :end-before: +``` + +% Include content from [../CONTRIBUTING.md](../CONTRIBUTING.md) +```{include} ../../CONTRIBUTING.md + :start-after: + :end-before: +``` diff --git a/docs/howto/index.md b/docs/howto/index.md new file mode 100644 index 0000000000..94a542b7eb --- /dev/null +++ b/docs/howto/index.md @@ -0,0 +1,13 @@ +(howtos)= + +# How-to guides + +```{toctree} +:titlesonly: + +Install authd +Configure authd +Login with GDM +Login with SSH +Contributing to Authd +``` diff --git a/docs/howto/install-authd.md b/docs/howto/install-authd.md new file mode 100644 index 0000000000..f1a4fb096f --- /dev/null +++ b/docs/howto/install-authd.md @@ -0,0 +1,41 @@ +# Installation + +This project consists of two components: +* authd: The authentication daemon responsible for managing access to the authentication mechanism. +* an identity broker: The services that handle the interface with an identity provider. There can be several identity brokers installed and enabled on the system. + +Authd is delivered as a Debian package. + +## System requirements + +* Distribution: Ubuntu Desktop 24.04 LTS or Ubuntu Server 24.04 LTS +* Architectures: amd64, arm64 + + +```{note} +While this project is in active development, a version for Ubuntu 24.04 is available from the [authd testing PPA](https://launchpad.net/~ubuntu-enterprise-desktop/+archive/ubuntu/authd).
+ +You can add this PPA to your system's software sources with the following commands: + +```shell +sudo add-apt-repository ppa:ubuntu-enterprise-desktop/authd +sudo apt update +``` + +Install the following Debian packages (note that `gnome-shell` and `yaru-theme*` are only required for desktop integration, server installations may ignore them): + +```shell +sudo apt install authd gnome-shell yaru-theme-gnome-shell +``` + +## MS Entra ID broker + +The brokers are provided as Snap packages and available from the Snap Store. + +To install the MS Entra ID broker, run the following command: + +```shell +sudo snap install authd-msentraid +``` + +At this stage, you have installed the main service and an identity broker to authenticate against Microsoft Entra ID. diff --git a/docs/howto/login-gdm.md b/docs/howto/login-gdm.md new file mode 100644 index 0000000000..a03919555f --- /dev/null +++ b/docs/howto/login-gdm.md @@ -0,0 +1,61 @@ +# Login with GDM + +## Logging in with a remote provider + +Once the system is configured you can log into your system using your MS Entra ID credentials and the device code flow. + +In the login screen (greeter), select ```not listed``` below the user name field. + +Type your MS Entra ID user name. The format is ```user@domain.name``` + +Select the broker `Microsoft Entra ID` + +![image](../assets/gdm-select-broker.png) + +If MFA is enabled, a QR code and a login code are displayed. + +![image](../assets/gdm-qr.png) + +From a second device, flash the QR code or type the URL in a web browser, then follow the authentication process from your provider. + +Upon successful authentication, the user is prompted to enter a local password. This password can be used for offline authentication. + +![image](../assets/gdm-pass.png) + +## Groups management + +In our example the user `authd test` is a member of the following Azure groups: + +![image](../assets/gdm-groups.png) + +This translates to the following unix groups on the local machine: + +```shell +~$ groups +aadtest-testauthd@uaadtest.onmicrosoft.com sudo azure_oidc_test +``` + +There are three types of groups: +1. **Primary group**: Created automatically based on the user name +1. **Local group**: Group local to the machine prefixed with `linux-`. For instance if the user is a member of the Azure group `linux-sudo`, they will be a member of the `sudo` group locally. +1. **Remote group**: All the other Azure groups the user is a member of. + +## Commands + +### authd + +```authd``` is socket-activated. It means that the service starts on-demand when it receives a request on a socket. + +If you want to restart the service, you can stop it with ```systemctl stop authd``` and it will restart automatically on the next message it receives. + +Run ```/usr/libexec/authd --help``` to display the entire help. + +## Entra ID broker + +The broker is managed through the ```snap``` command. + +The main operation is to restart the broker to reload the configuration when it has changed. You can reload the broker with the command: + +```shell +snap restart authd-msentraid +``` diff --git a/docs/howto/login-ssh.md b/docs/howto/login-ssh.md new file mode 100644 index 0000000000..9853fa1518 --- /dev/null +++ b/docs/howto/login-ssh.md @@ -0,0 +1,60 @@ +# Login with SSH + +## Server configuration + +To enable SSH access with `authd` you must configure `sshd` and the broker. + +### SSH configuration + +To configure SSH, create a file `/etc/ssh/sshd_config.d/authd.conf` with the following content: + +``` +UsePAM yes +KbdInteractiveAuthentication yes +``` + +Alternatively you can directly set the keys in the sshd configuration file `/etc/ssh/sshd_config`. + +Then restart the SSH server: + +``` +sudo systemctl restart ssh +``` + +### Broker configuration + +To configure the broker edit the file `/var/snap/authd-msentraid/current/broker.conf` and set the key `ssh_allowed_suffixes` with the list of domains that you want to allow. + +``` +[oidc] +issuer = https://login.microsoftonline.com//v2.0 +client_id = + +[users] +# The directory where the home directory will be created for new users. +# Existing users will keep their current directory. +# The user home directory will be created in the format of {home_base_dir}/{username} +# home_base_dir = /home + +# The username suffixes that are allowed to login via ssh without existing previously in the system. +# The suffixes must be separated by commas. +ssh_allowed_suffixes = +``` + +You can set several domains separated by a comma. For instance: + +``` +ssh_allowed_suffixes = @example.com,@ubuntu.com +``` + +## Usage + +Once this is all set up, you can ssh to the server in the same way you'd do with any server: `ssh @`. The format of `` is the user handle on Entra ID such as `user@domain.tld`. + +For instance: + +```shell +ssh user@domain.tld@remote.host +``` + +![image](../assets/ssh-qr.png) diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000000..d278be5a77 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,59 @@ +# Authd + +Authd is a versatile authentication service for Ubuntu, designed to seamlessly integrate with cloud identity providers like OpenID Connect and Entra ID. It offers a secure interface for system authentication, enabling cloud-based identity management. It can be used to support logins through both GDM and SSH. + +Authd features a modular structure, facilitating straightforward integration with different cloud services. This design aids in maintaining strong security and effective user authentication. It's well-suited for handling access to cloud identities, offering a balance of security and ease of use. + +Authd uses brokers to interface with cloud identity providers through a [DBus API](https://github.com/ubuntu/authd/blob/HEAD/examplebroker/com.ubuntu.auth.ExampleBroker.xml). Currently only [MS Entra ID](https://learn.microsoft.com/en-us/entra/fundamentals/whatis) is supported. For development purposes, Authd also provides an example broker to help you develop your own. + +The [MS Entra ID broker](https://github.com/ubuntu/oidc-broker) allows you to authenticate against MS Entra ID using MFA and the device authentication flow. + +--------- + +## In this documentation + + +````{grid} 1 1 1 1 + +```{grid-item-card} [How-to guides](index) + +**Step-by-step guides** covering key operations and common tasks +``` + +```` + +````{grid} 1 1 2 2 +:reverse: + +```{grid-item-card} [Reference](index) + +**Technical information** on troubleshooting authd +``` + +```{grid-item-card} [Explanations](index) + +**Discussion** of product architecture +``` + +```` + +--------- + +## Project and community + +Authd is a member of the Ubuntu family. It’s an open source project that warmly welcomes community projects, contributions, suggestions, fixes and constructive feedback. + +* [Code of conduct](https://ubuntu.com/community/ethos/code-of-conduct) +* [Contribute](/howto/contributing) + +Thinking about using Authd for your next project? Get in touch! + +```{toctree} +:hidden: +:maxdepth: 2 + +Authd +How-to guides +Reference +Explanation +``` diff --git a/docs/reference/index.md b/docs/reference/index.md new file mode 100644 index 0000000000..98b27c8785 --- /dev/null +++ b/docs/reference/index.md @@ -0,0 +1,9 @@ +(reference)= + +# Reference + +```{toctree} +:titlesonly: + +Troubleshooting +``` diff --git a/docs/reference/troubleshooting.md b/docs/reference/troubleshooting.md new file mode 100644 index 0000000000..fa3736a42b --- /dev/null +++ b/docs/reference/troubleshooting.md @@ -0,0 +1,111 @@ +# Troubleshooting + +## Logging + +```authd``` and the brokers are all logging to the system journal. + +For ```authd``` entries, run: + +```shell +journalctl -u authd.service +``` + +For the MS Entra ID broker entries, run: + +```shell +journalctl -u snap.authd-msentraid.authd-msentraid.service +``` + +For the GDM integration: + +```shell +journalctl /usr/bin/gnome-shell +``` + +For anything else or more broader investigation, use ```journalctl```. + +### Logging verbosity + +You can increase the verbosity of the logs in different ways. + +#### PAM module + +Append ```debug=true``` to all the lines with `pam_authd_exec.so` or `pam_authd.so` in the PAM configuration files (`common-auth`, `gdm-authd`...) in ```/etc/pam.d/``` to increase the verbosity of the PAM messages. + +#### NSS module + +Export `AUTHD_NSS_INFO=stderr` environment variable on any program using the authd NSS module to get more info on NSS requests to authd. + +#### authd service + +To increase the verbosity of the service itself, edit the service file: + +```shell +sudo systemctl edit authd.service +``` + +Add the following lines to the override file and make sure to add `-vv` at the end of the `authd` command: + +``` +[Service] +ExecStart= +ExecStart=/usr/libexec/authd -vv +``` + +Then you need to restart the service with `sudo systemctl restart authd`. + +#### GDM + +Ensure the lines in `/etc/gdm3/custom.conf` are not commented: + +```ini +[debug] +# Uncomment the line below to turn on debugging +# More verbose logs +# Additionally lets the X server dump core if it crashes +Enable=true +``` + +Then you need to restart the service with `sudo systemctl restart gdm`. + +#### authd-msentraid service + +To increase the verbosity of the broker service, edit the service file: + +```shell +sudo systemctl edit snap.authd-msentraid.authd-msentraid.service +``` + +Add the following lines to the override file and make sure to add `-vv` to the exec command: + +``` +[Service] +ExecStart= +ExecStart=/usr/bin/snap run authd-msentraid -vv +``` + +You will then need to restart the service with `snap restart authd-msentraid`. + +## Switch the snap to the edge channel + +Maybe your issue is already fixed! You should try switching to the edge channel of the broker snap. You can easily do that with: + +```shell +snap switch authd-msentraid --edge +snap refresh authd-msentraid +``` + +Keep in mind that this version is not tested and may be incompatible with current released version of authd. You should switch back to stable after trying the edge channel: + +```shell +snap switch authd-msentraid --stable +snap refresh authd-msentraid +``` + +## Common issues and limitations + +### File ownership on shared network resources (e.g. NFS) + +The user and group IDs assigned by authd are currently not guaranteed to be the same on different systems, so the same user can be assigned a different UID on different systems. That means that shared network resources like NFS which rely on UIDs and GIDs for access are currently not supported, because users might not be able to access their own files and might even be able to access files they should not be able to access. + +We are looking into how we can support this in the future. diff --git a/docs/reuse/links.txt b/docs/reuse/links.txt new file mode 100644 index 0000000000..f9d3d5cdc5 --- /dev/null +++ b/docs/reuse/links.txt @@ -0,0 +1 @@ +.. _link text: https://example.com