nts-sources.yml: Format, Schema, and Purpose Explained
The nts-sources.yml file is a YAML database that serves as the single source of truth for all Network Time Security (NTS) servers tracked by the repository, defining server metadata and enabling automated configuration generation for NTP daemons.
The jauderho/nts-servers repository maintains a curated list of public NTS servers for secure time synchronization. At the heart of this project lies nts-sources.yml, a structured YAML file that catalogs every server with essential metadata including hostname, stratum, and geographical location. This central file drives the entire automated pipeline that generates configuration files for Chrony and ntpd-rs while keeping documentation synchronized.
Understanding the nts-sources.yml Format
The nts-sources.yml file uses a straightforward schema designed for both human readability and machine parsing. According to the source code in jauderho/nts-servers, the file organizes data under a top-level servers key containing an ordered list of server descriptors.
YAML Schema and Required Fields
Each server entry in nts-sources.yml is a mapping with the following fields (as defined in lines 1-14 of the file):
hostname: String representing the DNS name. Supports plain text or Markdown link syntax (e.g.,"[time.cloudflare.com](https://time.cloudflare.com)").stratum: Integer indicating the NTP stratum level (lower values indicate higher accuracy).location: String describing the geographical location (country or city).owner: String identifying the organization or individual responsible for the server.notes: Optional string for additional remarks such as "Anycast" or "IPv4 and IPv6".vm: Boolean flag set totrueif the server runs in a virtualized environment.
A minimal valid entry appears as:
- hostname: time.cloudflare.com
stratum: 3
location: All
owner: Cloudflare
notes: Anycast
vm: false
File Organization Requirements
The file enforces alphabetical grouping by country to ensure predictable editing and automated processing. As specified in AGENTS.md (lines 3-6), new entries must be inserted into the appropriate alphabetical section, making the raw YAML structure scannable and version-control friendly.
Core Purpose and Automation Pipeline
The nts-sources.yml file functions as the canonical definition for trusted NTS servers. Rather than maintaining separate lists for documentation and configuration, all downstream artifacts derive from this single source.
Configuration File Generation
The scripts/ntpServerConverter.py script consumes nts-sources.yml to produce three critical outputs:
chrony.conf: Chrony NTP daemon configuration generated bygenerate_chrony_conf(lines 59-77).ntp.toml: ntpd-rs configuration generated bygenerate_ntp_toml(lines 86-106).- README tables: Markdown documentation generated by
generate_markdown(lines 21-44).
Stratum Verification and Updates
To maintain accuracy, scripts/ntsUpdateServers.py reads the YAML file and queries each server using ntpdate or ntpq. The update_stratum_values function (lines 40-87) compares reported stratum values against the stored data and rewrites the file when discrepancies are detected.
Agent-Driven Automation
The repository's automated agent workflow (defined in AGENTS.md) inserts new servers directly into nts-sources.yml after validating NTS/NTP reachability. This ensures the central database remains current without requiring manual YAML editing for every new server.
Practical Usage Examples
Working with nts-sources.yml involves parsing Markdown-formatted hostnames, generating configurations, and updating metadata programmatically.
Extracting Hostnames from Markdown Links
When processing the hostname field, scripts must handle both plain text and Markdown link formats. The scripts/ntsUpdateServers.py implementation (lines 28-44) uses regex extraction:
import re
def extract_hostname(hostname_field):
"""
Accepts plain text or Markdown links like
'[time.cloudflare.com](https://time.cloudflare.com)'
Returns the raw hostname.
"""
markdown_match = re.match(r'\[([^\]]+)\]', hostname_field)
if markdown_match:
return markdown_match.group(1)
return hostname_field.strip()
Adding a New Server Entry
To manually append a server, insert into the appropriate alphabetical section following the established schema:
- hostname: "[time.example.de](https://time.example.de)"
stratum: 2
location: Germany
owner: Example Corp
notes: IPv4 and IPv6
vm: false
This format mirrors entries found in lines 71-78 of the source file.
Generating Configuration Files
Convert the YAML into usable NTP daemon configurations with:
python3 scripts/ntpServerConverter.py nts-sources.yml
This command writes chrony.conf, ntp.toml, and updates README.md using the conversion logic in generate_chrony_conf.
Updating Stratum Values Automatically
Verify and refresh stratum data without manual editing:
python3 scripts/ntsUpdateServers.py --dry-run # Preview changes
python3 scripts/ntsUpdateServers.py # Apply updates
The script loads the YAML via load_yaml_file, queries each host through get_stratum, and persists changes via save_yaml_file (see the main() function, lines 90-124).
Summary
nts-sources.ymlserves as the single source of truth for NTS server metadata in thejauderho/nts-serversrepository.- The YAML schema requires
hostname,stratum,location,owner, andvmfields, with optionalnotes. - Alphabetical grouping by country is mandatory per
AGENTS.mdrequirements. scripts/ntpServerConverter.pytransforms this file intochrony.conf,ntp.toml, and README documentation.scripts/ntsUpdateServers.pyautomates stratum verification and updates against live server data.- Hostname fields support Markdown link syntax, requiring regex parsing in downstream tools.
Frequently Asked Questions
What is the exact structure of the nts-sources.yml file?
The file contains a top-level servers key mapped to an ordered list of server entries. Each entry is a YAML mapping with six fields: hostname (string, supports Markdown), stratum (integer), location (string), owner (string), notes (optional string), and vm (boolean). The entire list is organized alphabetically by country to facilitate automated agent workflows.
How does the repository use nts-sources.yml to generate configs?
The Python script scripts/ntpServerConverter.py parses the YAML and invokes specialized generators: generate_chrony_conf produces Chrony daemon configurations, generate_ntp_toml creates ntpd-rs settings, and generate_markdown renders the server table for documentation. All outputs derive from this single YAML source to ensure consistency across the repository.
Can hostnames in nts-sources.yml contain formatting or URLs?
Yes. The hostname field accepts either plain text (e.g., time.cloudflare.com) or Markdown hyperlink syntax (e.g., [time.cloudflare.com](https://time.cloudflare.com)). Downstream tools like scripts/ntsUpdateServers.py extract the raw hostname using regex patterns to handle both formats correctly during stratum verification.
How are stratum values in nts-sources.yml kept accurate?
The scripts/ntsUpdateServers.py utility automates this process. It loads the YAML, queries each server using standard NTP tools (ntpdate/ntpq), and updates the stratum field if the live value differs from the stored value. Run with --dry-run to preview changes before applying them to the canonical file.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →