DEV Community

Parental Controls with Kiro IDE, AWS, and NextDNS

Note: I'm a Japanese developer, so some screenshots contain Japanese text. I hope that's okay!

Hi there.
I'm Kaneyasu from the Application Services Division (DevOps) at Serverworks.
This time, I'd like to share a personal project where I used Kiro IDE to build parental controls.
Think of it as a story of turning a small idea into reality using spec-driven development.

Introduction

This is about my own family's situation.
I want to be clear that I don't believe parental control is an absolute must in child-rearing.

Parental Controls with NextDNS

On the personal side, I have a middle school-aged kid.
They have a smartphone, but tend to stay up late browsing manga sites at night. After a family discussion, we decided to block certain sites during late-night hours until they can manage their own sleep schedule.

To achieve this, I used a service called NextDNS.

NextDNS provides private DNS. On Android, you can typically configure it under [Network & Internet] > Private DNS.
By routing through private DNS, you can block access to specific sites from the phone.

NextDNS - The new firewall for the modern Internet

The new firewall for the modern Internet

nextdns.io

Refer to the NextDNS official docs for detailed setup. In short:

  • Set up a private DNS with NextDNS
  • Add specific sites to the denylist
  • Configure the phone's DNS settings to use NextDNS

This way, the phone connects to the internet through private DNS, and access to specific sites is blocked.
The nice thing about this approach is that it's difficult to bypass unless you know about private DNS and how it works.

NextDNS has built-in parental control features with pre-registered sites. These can be toggled ON/OFF by time of day using the "Recreation Time" feature.
However, sites not in the default list can only be blocked via the "Denylist", which doesn't support time-based toggling.

On the other hand, NextDNS provides an API that allows toggling the denylist ON/OFF programmatically.

NextDNS API Documentation

I combined the NextDNS API with AWS and built the parental controls my family needed using Kiro IDE.

System Architecture

Here's the system architecture I envisioned.
Amazon EventBridge Scheduler triggers an AWS Lambda function at night and in the morning to operate NextDNS.
Sites my kid frequently visits are registered in the NextDNS "Denylist", and Lambda toggles them ON/OFF via the API.

System Architecture

Spec-Driven Development with Kiro IDE

With the above architecture in mind, I developed in two stages using Kiro:

  • PoC (verify technical feasibility), then write a verification report, product overview, and tech stack
  • Implement based on the verification report, product overview, and tech stack

Honestly, I was fairly confident there wouldn't be technical issues, but I wanted to avoid wasting Kiro tokens and time if something unexpected came up. I've also learned from experience that vague instructions lead to rework, so I split it into two stages.

Related post (Japanese):Kiro IDEと一緒に技術検証してみたところ、自分が熟慮せずに指示を出してることに気づいた話

PoC Spec

With the plan decided, I created and executed the PoC Spec.
Here's the initial prompt I entered:

I want to implement parental controls for my kid's smartphone using NextDNS.
I want to block access to specific sites from late night to early morning.
By setting NextDNS private DNS on the phone, I can restrict the phone's traffic.
Domains in the default list can be toggled ON/OFF by time using
"Parental Controls" > "Recreation Time".
However, what I want to control are domains NOT in the default list.
These can be blocked via a custom domain list called "Denylist",
but it doesn't support time-based toggling.
NextDNS has an API, so I'm thinking of calling the API externally
on a schedule to achieve this.
Please verify feasibility using the URL below as reference.
https://nextdns.github.io/api/
I already have an account so I can obtain an API key.
Enter fullscreen mode Exit fullscreen mode

This prompt generated requirements.md.
At this point I remembered this was supposed to be a PoC, so I added another prompt:

Let's treat this Spec as a PoC.

Verify with simple test code and set the goal as creating a report,
product overview, and tech stack documentation under docs/
for the subsequent main development.
Enter fullscreen mode Exit fullscreen mode

I then added a requirement that test code execution should be done manually, and finalized requirements.md.
Then design.md and tasks.md were created.
Here's the outline of tasks.md:

  1. Project initial setup
  2. NextDNS API client implementation
  3. PoC script implementation
  4. Checkpoint - manual execution and verification
  5. Documentation creation

Task 4 was written in tasks.md like this:

- [ ] 4. Checkpoint - manual execution and verification
  - Create `.env` file and set actual API key
  - Run `npm run poc` to verify
  - Ensure all steps pass, ask the user if questions arise.
Enter fullscreen mode Exit fullscreen mode

I made this a manual step because I didn't want a potentially broken script to be executed automatically.
After reviewing tasks.md and running it, when it reached step 4, the following message appeared and it properly paused:

Pause for manual verification

I entered the manual execution results as a prompt and continued tasks.md. The verification report, product overview, and tech stack were all completed.

nextdns-parental-controls/
├── config/
│   └── schedule-config.json
├── docs/
│   ├── poc-report.md        # PoC verification report
│   ├── product-overview.md  # Product overview
│   └── tech-stack.md        # Tech stack
├── scripts/
│   └── poc.ts
├── src/
│   └── nextdns-client.ts
├── package.json
├── tsconfig.json
└── README.md
Enter fullscreen mode Exit fullscreen mode

I later noticed some issues with the tech stack produced here. More on that in the retrospective section.

Implementation Spec

In the Spec creation screen, I instructed it to implement based on the verification report, product overview, and tech stack from the PoC Spec.
Once the new requirements.md was generated, I ran Analyze requirements to improve requirement precision.

Kiro IDE - Analyze Requirements

Analyze requirements checks for logical inconsistencies, ambiguities, and gaps.

Running Analyze requirements on requirements.md

In this Spec, it provided detailed verification about the Secrets Manager permissions to grant to the Lambda function.

Verification items from Analyze requirements

My impression is that Analyze requirements isn't as granular as aidlc-workflows, but it provides appropriate checks.
Once requirements.md was finalized with Analyze requirements, it was just a matter of proceeding through design.md and tasks.md to complete the implementation.
The implementation was completed and my family's desired parental controls are now up and running.

Retrospective and Lessons Learned

The implementation probably could have been done in one shot without the PoC, but verifying feasibility first gave me peace of mind.
The PoC Spec was designed with implementation deferred, with the goal of producing documentation.
In real-world projects, there are many tasks where documentation is the deliverable, so I think treating Specs this way makes them more applicable to actual work.

Regarding the tech stack produced by the Spec, I noticed several issues:

  • Language versions (TypeScript, Node.js) were slightly outdated
  • The scheduling implementation was slightly outdated (used EventBridge Rules instead of EventBridge Scheduler)
  • Lint/formatter tooling wasn't fully configured

These kinds of issues come up frequently in spec-driven development. From my experience, this happens regardless of the tool, not just with Kiro IDE. It's worth keeping in mind during review that these things commonly occur.

After implementation was complete, I found that deploying with IaC produced an error.
I used AWS CDK for IaC, and the cause was a simple import error that slipped through despite having unit tests.
This could have been caught by including a dry-run check (cdk synth) in the tasks.md checkpoint, not just unit tests.
I should have added that instruction earlier. Proactive instructions likely reduce AI costs in spec-driven development, and that's something to be mindful of.

Total time to completion was about 4 hours including post-deployment manual testing.
Up to implementation completion, it was under 3 hours.
However, this assumes my existing experience and knowledge of where spec-driven development tends to have gaps.
Without this background knowledge, it would likely take twice as long, or you might discover version issues only after the fact.

Conclusion

The parental controls I built are running smoothly to this day.
If my kid figures out private DNS and disables it, I'll think of something else.

The code is available here:

https://github.com/satoshi256kbyte/nextdns-parental-controls

By the way, if my kid reads this article the whole scheme would be exposed immediately. But realistically, it's hard for them to stumble upon it, and they probably wouldn't want to read their dad's tech blog anyway — I imagine they'd close the tab after the first two lines of self-introduction. So I'm not too worried.

Top comments (0)