DEV Community

Xalen Technologies
Xalen Technologies

Posted on

You're One Audit Away From Open-Sourcing Your Astrology App

 "Almost every horoscope app on earth links Swiss Ephemeris. Alm
ost none of them have read its license. Here's the clause that can force you
to open-source your entire backend, and the pure-Rust, Apache-2.0 way out."
tags: opensource, legal, rust, startups

Your Astrology SaaS Is an AGPL Time Bomb

Here's how your astrology app was probably born.

It needed planetary positions. A search for "ephemeris library" led, like every
road does, to Swiss Ephemeris, the C library from Astrodienst that astro.com
itself runs on. So pip install pyswisseph, a call to swe.calc_ut(), the Moon comes back in the right place, and it ships.

Nobody opened the license.

So let's open it, because the clause sitting inside it can legally obligate you to publish the complete source code of your entire backend to every user who hits your API. And a closed-source product running on pyswisseph right now is
already in violation.

The two-line version

Swiss Ephemeris is dual-licensed:

  1. AGPL-3.0, free, but copyleft with a network clause, or
  2. A paid commercial license from Astrodienst.

There is no third door. Without the commercial license, you took the AGPL.Using the software accepted its terms. Most people building on Swiss don't know they made that choice, but they made it.

The clause that eats your business: AGPL Section 13

The regular GPL has a famous loophole for SaaS: copyleft triggers on
distribution, and running software on your own server for users to access over a network is not distribution. That's how Google runs GPL code internally without publishing anything. It's sometimes called the "ASP loophole."

The A in AGPL exists for the sole purpose of slamming that loophole shut.
Here's the actual operative language from Section 13:

"...if you modify the Program, your modified version must prominently offer
all users interacting with it remotely through a computer network ... an
opportunity to receive the Corresponding Source of your version..."

Read that again with your product in mind. "All users interacting with it remotely through a computer network" is a precise description of every web astrology app ever built. Users hit your endpoint. Your endpoint computes a chart using Swiss Ephemeris. Section 13 says those users are entitled to your Corresponding Source, and "Corresponding Source" is defined broadly enough to reach the code wrapped around the library.

This is not a theoretical edge case. It is the designed, intended behavior of the license. The AGPL is working exactly as specified when it does this to you.

"But it's just being called, not modified"

This is the rationalization everyone reaches for, so let's kill it.

pyswisseph is not a separate thing. It's a thin C-extension wrapper that links libswe directly. It inherits Swiss Ephemeris's license wholesale: the pyswisseph project says so itself. import swisseph is import AGPL. There is no Python-shaped escape hatch.
And the "it wasn't modified" defense is thinner than it feels:

  • The FSF's own position is that linking creates a combined work. Whether your service is a "modified version" or a "work based on the Program" under the AGPL is exactly the kind of question you do not want a lawyer answering for the first time during due diligence on your acquisition.
  • Even on the most charitable reading, the whole company is now riding on a copyleft-boundary argument. That's not a foundation. That's a fault line.

The honest summary Astrodienst themselves push you toward: a service that isn't open-sourced needs the commercial license. That's the whole reason the commercial license exists. They are not selling it for fun. They are selling it to the exact people reading this post.

When the bomb actually goes off

AGPL violations rarely blow up on day one. They blow up at the worst possible moment, because that's when someone finally reads the dependency manifest:

  • Fundraising / acquisition due diligence. The acquirer's legal team runs a license scan. AGPL-3.0 lights up red next to your core IP. The deal stalls while you scramble to either rip out the dependency or back-pay a commercial license. This exact scenario has tanked timelines.
  • An enterprise customer's security review. Big-co procurement runs an SCA(software composition analysis) tool. AGPL is on their banned-license list, and it is on most corporate banned lists, precisely because of Section 13. Your deal is now blocked on a license remediation that can't happen overnight.
  • A competitor or a disgruntled user files a complaint. Now the choice is between publishing your crown jewels and writing Astrodienst a check sized by someone who knows you have no leverage.

The cost of an AGPL dependency isn't zero just because nobody's invoiced
you yet.It's a contingent liability sitting on your balance sheet, and it comes due exactly when you can least afford it.

The way out: same accuracy, sane license

For thirty years the trade-off was brutal and unspoken: the only JPL-accurate ephemeris was AGPL/commercial C. The permissive alternatives (astro,practical-astronomy-rust on crates.io) are lovely little textbook crates:arcminute-grade, astronomy-only, no astrology layer. So everyone held their nose and took the AGPL, because there was no other accurate option.

There is now. It's called XALEN Ephemeris, and it's Apache-2.0.

Apache-2.0 is the opposite of AGPL in every way that matters here:

AGPL-3.0 (Swiss) Apache-2.0 (XALEN)
Use in closed-source SaaS triggers Section 13 yes
Per-deployment / commercial fee or open everything none
Network/copyleft clause yes none
Patent grant no explicit
Obligation Publish your source Keep the attribution notice

Ship it in a closed-source product, keep the source private, and the only duty is to preserve the license notice. That's the entire deal.

And there's no accuracy tax

The catch with "permissive ephemeris" used to be that permissive meant
inaccurate. Not here. XALEN's numbers are reproducible from its own test suite(cargo test --workspace, 2,199 passing), measured against JPL Horizons DE440, the same reference Swiss reads:

  • Sun: 0.21″
  • Mercury–Saturn: ≤ 0.76″, with zero data files (VSOP87A compiled in)
  • Moon: RMS ~2.8″ analytically; sub-arcsecond with the optional DE440 kernel
  • 5,000,000-chart diff vs Swiss Ephemeris: 0 charts off by more than 0.1°

And because it's pure Rust with zero unsafe in the computation core, no process-global state, and a Send + Sync engine, Swiss's other two headaches go away too: the .se1 data files you have to ship and the global swe_set_*state you have to mutex. But honestly? Even if XALEN were only "Swiss accuracy with a license that doesn't threaten your company," that would be enough to switch.

XALEN ships a Swiss-compatible shim specifically to make door #3 cheap: a
swe_calc_ut(jd, SE_SUN, ...) surface with the same xx[0..6] array semantics already in your code, so migration is closer to search-and-replace than rewrite.

The AGPL clause has been sitting in your stack this whole time. It didn't go off because nobody looked, not because it's safe. Look now, while looking is cheap.

→ *github.com/vedika-io/xalen-ephemeris

Top comments (0)