--- /dev/null
+= README
+
+Simple and fast configuration management (safcm) is written in Go and licensed
+under GPLv3+. It is:
+
+- *simple*: to use and implement, obvious concepts and less bugs
+- *fast*: to learn and to use, quickly apply new configurations to your hosts
+- *configuration management*: sync files, packages, services and run commands
+ on remote hosts
+
+The goal is that even unexperienced users (with safcm or configuration
+management in general) should be able to apply configuration with safcm
+quickly. This means all key concepts of safcm must be easy to grasp and for
+each task there should be one obvious way.
+
+It can also be read as "saf(e) configuration management" as it combines
+simplicity and safety in the following principles:
+
+- *fail fast*: catch (user) errors as soon as possible; host configuration
+ (including templates) evaluated locally to prevent partial configuration;
+ errors immediately abort the synchronization
+- *remote hosts untrusted*: clear security boundary between local and remote
+ host; data used from remote hosts is marked (detected groups); all output
+ from remote hosts is escaped to prevent terminal injection attacks; each
+ host only receives its configuration and no data from other hosts
+- *safety and security*: create files with "write to temporary file", "sync",
+ "rename", "sync directory" for atomicity and durability; guard against
+ symlink and other TOCTOU attacks; extensive test suite
+
+
+== Overview
+
+This section describes the general concepts, behavior and terminology of
+safcm.
+
+Safcm _synchronizes_ _files_, _packages_, _services_ and _commands_ to remote
+_hosts_. All hosts are explicitly configured. Hosts can be put into _groups_
+to apply the same configuration to multiple hosts. The host itself is also
+considered a group for host-specific configuration. In addition to manual
+group assignment _detected groups_ assign hosts to groups depending on the
+output of custom commands on the remote host. The configuration for a group
+contains the files, packages, services and commands which should be applied to
+all hosts which are members of this group.
+
+The configuration of all managed hosts is stored in a directory on the local
+host. Safcm uses https://yaml.org/[YAML] for all configuration files. However,
+tasks like copying a file require no explicit configuration (see the
+documentation for details).
+
+Files consist of a tree of files (regular files and symbolic links) and
+directories with permissions, user/group and content. Files can use
+_templates_ for dynamic content depending on the host or its groups. Each path
+can have _trigger_ commands which are executed when the path itself or any
+sub-paths are modified during synchronization. Packages are package names of
+the remote operating system. Services are service names of the remote
+operating system. Commands are shell commands passed to `/bin/sh`.
+
+When files with the same path are present in multiple groups of a host an
+explicit _group order_ must be configured to resolve the conflict. Conflicts
+do not apply to packages and services which are simply merged from all groups.
+Commands are appended so that the same command can be executed multiple times.
+
+To sync the configuration to a remote host the local `safcm` binary connects
+to it via `ssh`. It then copies a _remote helper_ binary to `/tmp` on the
+remote host to later perform the actual sync. If the remote helper is already
+present, has the proper checksum, permissions and user then the copy is
+skipped. `safcm` then queries the remote host for information, including
+operating system, architecture and detected groups. With all relevant data
+collected it assigns the host its groups, evaluates the configuration
+including templates and finally sends it to the remote helper which then
+applies it to the remote host.
+
+The synchronization happens in the following order which cannot be changed:
+
+. Collect information from remote helper including detected groups
+. Build configuration for the host and send it to the remote helper
+. Apply the configuration using the remote helper
+.. Synchronize files
+.. Install packages
+.. Enable/Start services
+.. Run triggers
+.. Run commands
+
+After the synchronization is complete (or on the first error) the applied
+changes are displayed. Multiple hosts are synchronized in parallel.
+
+
+== Limitations & Gotchas
+
+Besides some obvious limitations due to the simplicity of safcm there are a
+few issues the user should be aware of. Some of these might get fixed in the
+future, others are due to the design of safcm.
+
+- Commands are executed with `/bin/sh -c` on the remote host which might leak
+ sensitive information to other users via the command line (unless `/proc` is
+ mounted with `hidepid=`). Store sensitive data in a file and execute or
+ source it as a workaround.
+
+- Permissions of existing files and directories will be overwritten with the
+ default (root/root, 0644 for files, 0755 for directories) unless manually
+ configured via `permissions.yaml`. This includes important paths like
+ `/root` which often have strict permissions by default, so carefully check
+ the diff output for unwanted changes.
+
+
+== Requirements
+
+- build the `safcm` binary and remote helper:
+ * Go >= 1.16
+ * GNU make
+
+- local host:
+ * Go support for architecture and operating system, see the "$GOOS and
+ $GOARCH" section in the official
+ https://golang.org/doc/install/source#environment[Go installation guide]
+
+- *remote hosts*:
+ * Go support for architecture and operating system
+ * GNU/Linux with common commands (`stat`, `sha512sum`, `cat`, `rm`, `ln`,
+ `chmod`)
+ * SSH server
+ * to install packages:
+ ** `apt-get` (Debian or derivative)
+ * to sync services:
+ ** `systemd`
+
+Adding support for other operating systems (e.g. BSDs) or distributions
+including package managers (e.g. Arch, Gentoo) is easy. Please send patches.
+
+
+== Authors
+
+Written by Simon Ruderich <simon@ruderich.org>.
+
+
+== License
+
+This program is licensed under GPL version 3 or later.
+
+Copyright (C) 2021 Simon Ruderich
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.