# How is-a.dev Enforces Subdomain Naming Conventions: Multi-Layer Validation Explained

> Discover how is-a.dev enforces subdomain naming conventions with multi-layer validation including JSON block lists CI filename checks and DNS record generation Learn about their robust security.

- Repository: [is-a.dev/register](https://github.com/is-a-dev/register)
- Tags: deep-dive
- Published: 2026-03-09

---

**is-a.dev guarantees subdomain compliance through a three-tier defense system combining static JSON block lists, automated CI filename validation, and synthetic DNS record generation.**

The **is-a-dev/register** repository manages thousands of free subdomains under the `is-a.dev` namespace. To maintain DNS integrity and prevent routing conflicts, the project implements rigorous **is-a.dev subdomain naming conventions** enforced automatically during every pull request via the [`tests/json.test.js`](https://github.com/is-a-dev/register/blob/main/tests/json.test.js) validation suite.

## Static Block Lists for Reserved and Internal Names

### Globally Reserved Subdomains

The foundation of the naming policy lives in [`util/reserved.json`](https://github.com/is-a-dev/register/blob/main/util/reserved.json), a static array of strings representing names prohibited for user registration. This list includes high-risk terms like `admin`, `api`, and `dev` that could create security vulnerabilities or routing ambiguities if claimed by individual users.

### Internal System Subdomains

Platform infrastructure names such as `www` and `ns1` are cataloged in [`util/internal.json`](https://github.com/is-a-dev/register/blob/main/util/internal.json). These entries represent subdomains reserved for the service's own operational needs, ensuring that critical DNS records remain under administrative control and cannot be overwritten by user submissions.

## Automated CI Validation with validateFileName

### Block List Enforcement in Tests

When a contributor opens a pull request, the CI suite in [`tests/json.test.js`](https://github.com/is-a-dev/register/blob/main/tests/json.test.js) (lines 35-36) loads both block lists and validates the proposed subdomain against them:

```javascript
const internalDomains = require("../util/internal.json");
const reservedDomains = require("../util/reserved.json");

// Validation checks:
t.false(internalDomains.includes(subdomain), `${file}: Subdomain name is registered internally`);
t.false(reservedDomains.includes(subdomain), `${file}: Subdomain name is reserved`);

```

Any filename matching entries in these arrays triggers an immediate test failure, blocking the merge and preventing namespace collisions.

### Syntax and Hostname Compliance

The `validateFileName` function (lines 96-118 of [`tests/json.test.js`](https://github.com/is-a-dev/register/blob/main/tests/json.test.js)) applies **RFC 1123** hostname validation through regex and string analysis. This function enforces the following critical rules:

- **Filename structure**: Must end with `.json` and must not contain the literal string `.is-a.dev`
- **Character restrictions**: All lowercase letters, no consecutive hyphens (`--`), and valid hostname characters only
- **Length limits**: Maximum 253 characters per DNS standards
- **Root label restrictions**: The left-most subdomain label cannot start with an underscore (checked via `t.false(rootSubdomain.startsWith("_"))` on lines 17-18)
- **Suffix protection**: Subdomains cannot end with reserved or internal names (verified via `!internalDomains.some(i => subdomain.endsWith('.' + i))` on lines 12-15)

## Synthetic Record Generation and DNS Guards

### Automatic System Record Creation

The [`util/raw-api.js`](https://github.com/is-a-dev/register/blob/main/util/raw-api.js) script (lines 14-54) preemptively generates DNS entries for all internal and reserved names, writing them to [`raw-api/v2.json`](https://github.com/is-a-dev/register/blob/main/raw-api/v2.json) before processing user submissions. This ensures protected names always resolve to controlled endpoints, such as `CNAME: "internal.is-a.dev"` for internal services or `URL: "https://is-a.dev/reserved"` for blocked terms.

### DNS Configuration Enforcement

In [`dnsconfig.js`](https://github.com/is-a-dev/register/blob/main/dnsconfig.js) (lines 142-144), the build process explicitly creates A records for reserved names while ignoring them in public zone generation (lines 166-167). This mirrors the validation logic at the infrastructure layer, preventing edge cases where test-validated files might bypass DNS-level protections.

## Practical Examples of Validation

### Valid Subdomain Registration

A compliant submission for `example.is-a.dev` uses the filename [`example.json`](https://github.com/is-a-dev/register/blob/main/example.json):

```json
{
  "owner": {
    "username": "alice"
  },
  "records": {
    "A": ["192.0.2.10"]
  }
}

```

This passes all checks: lowercase, no double hyphens, valid hostname syntax, and no block list matches.

### Invalid: Reserved Name Violation

Attempting to register [`admin.json`](https://github.com/is-a-dev/register/blob/main/admin.json) fails during CI execution because `"admin"` appears in [`util/reserved.json`](https://github.com/is-a-dev/register/blob/main/util/reserved.json). The test suite outputs: `admin.json: Subdomain name is reserved`.

### Invalid: Underscore in Root Label

A file named [`_private.json`](https://github.com/is-a-dev/register/blob/main/_private.json) fails the specific check:

```javascript
t.false(rootSubdomain.startsWith("_"), `${file}: Root subdomains should not start with an underscore`);

```

The PR is rejected despite passing other hostname regex validations.

## Summary

- **Static block lists** in [`util/reserved.json`](https://github.com/is-a-dev/register/blob/main/util/reserved.json) and [`util/internal.json`](https://github.com/is-a-dev/register/blob/main/util/internal.json) define prohibited subdomain strings at the repository level.
- **Automated CI testing** via [`tests/json.test.js`](https://github.com/is-a-dev/register/blob/main/tests/json.test.js) validates filenames against RFC 1123 standards, syntax rules, and block list membership before merge.
- **Synthetic record generation** in [`util/raw-api.js`](https://github.com/is-a-dev/register/blob/main/util/raw-api.js) ensures reserved names always resolve to platform-controlled endpoints, preventing accidental overwrites.
- **DNS configuration guards** in [`dnsconfig.js`](https://github.com/is-a-dev/register/blob/main/dnsconfig.js) apply the same restrictions during zone file compilation, maintaining consistency between validation and deployment.

## Frequently Asked Questions

### What characters are allowed in is-a.dev subdomains?

Subdomains must use lowercase letters, digits, dots, and single hyphens only. The `validateFileName` function rejects uppercase characters, consecutive hyphens (`--`), and underscores in root labels through strict regex validation matching RFC 1123 hostname standards.

### Can I register a subdomain that starts with an underscore?

No. The validation code explicitly checks `t.false(rootSubdomain.startsWith("_"))` to prevent root labels from beginning with underscores. While DNS technically permits underscores in some service record contexts, is-a.dev blocks them at the root level to avoid conflicts with platform infrastructure and future service implementations.

### How does is-a.dev prevent conflicts with system subdomains?

The platform maintains [`util/internal.json`](https://github.com/is-a-dev/register/blob/main/util/internal.json) containing operational names like `www` and `ns1`. During CI execution, [`tests/json.test.js`](https://github.com/is-a-dev/register/blob/main/tests/json.test.js) verifies that no proposed subdomain matches these protected strings exactly or ends with them as suffixes, while [`util/raw-api.js`](https://github.com/is-a-dev/register/blob/main/util/raw-api.js) generates synthetic records to ensure these names always resolve to internal endpoints.

### Where are the reserved and internal subdomain lists defined?

Reserved names (globally blocked terms like `admin` and `api`) live in [`util/reserved.json`](https://github.com/is-a-dev/register/blob/main/util/reserved.json), while internal platform names reside in [`util/internal.json`](https://github.com/is-a-dev/register/blob/main/util/internal.json). Both files are simple JSON arrays consumed by the validation suite in [`tests/json.test.js`](https://github.com/is-a-dev/register/blob/main/tests/json.test.js) and the API generation script in [`util/raw-api.js`](https://github.com/is-a-dev/register/blob/main/util/raw-api.js), ensuring consistent enforcement across the entire registration pipeline.