
TuJu's Privacy Policy Has Four Gaps
TuJu's Privacy Policy Has Four Gaps
On 20 October 2026, the government told every civil servant in Malaysia to stop using Waze while on official duty and to switch to a locally developed navigation app. NACSA's FAQ names TuJu and PINTAZ as the alternatives. On 22 October, SoyaCincau published a hands-on review of TuJu and found the turn-by-turn navigation "frustratingly bad".
Both stories are about usability and sovereignty. Neither touches the paperwork: the privacy policy attached to the app you are being told to switch to. We scored TuJu's policy against NACSA's own risk framework and against the data-protection duties that apply to whoever operates it. TuJu came back with four gaps. Waze — the app being abandoned — stated every one of the same checks.
One note on register: this audits published documents, not legal advice, and a gap in a privacy policy is not proof that anyone broke the law.
NACSA wrote the checklist, so we turned it into eight checks
NACSA says the risk assessment for a navigation app must cover the types of data it accesses, the permissions it requires, the location and jurisdiction where data is processed, the storage policy and period, the mechanism for sharing data with third parties, and the security controls the provider implements.
That is a disclosure test, so we implemented it as one: six checks straight from NACSA, plus two from the Personal Data Protection Act 2010 — whether the policy names a legal framework, and whether it gives a reader a way to act on their data. We ran it against the two live policies, both fetched on 22 October 2026.
#!/usr/bin/env python3
"""Score a navigation app's privacy policy against NACSA's six risk factors.
The six factors come from NACSA's FAQ on the Waze directive (20 October 2026):
data types accessed, permissions granted to the app, where the data is
processed, storage policy and retention period, third-party sharing, and the
provider's security controls. Two extra checks cover PDPA 2010 duties that
map onto the same question - whether the policy names a legal framework and
whether it gives the data subject a way to act.
This measures *disclosure*, not compliance. A PASS means the policy says
something on the topic. UNSTATED means it says nothing, which is a finding in
its own right for a policy review.
Usage:
python3 privacy_policy_audit.py <privacy-policy-url> [--save out.txt]
"""
from __future__ import annotations
import argparse
import html
import re
import sys
import urllib.error
import urllib.request
# (label, strong patterns, weak patterns)
CHECKS: list[tuple[str, list[str], list[str]]] = [
(
"data types accessed",
[
r"location (?:information|data|information and data)",
r"gps",
r"transaction data",
r"usage data",
r"cell tower",
r"wi-?fi access point",
],
[r"we collect", r"information we collect", r"what we collect"],
),
(
"permissions granted to the app",
[
r"permission",
r"access to your location through your device settings",
r"device settings",
],
[r"location services"],
),
(
"where the data is processed",
[
r"servers located",
r"stored on servers",
r"data (?:is|are) stored in",
r"outside (?:of )?the country where you live",
r"processing (?:takes place|occurs) in",
r"jurisdiction",
],
[r"global", r"worldwide", r"cloud storage"],
),
(
"storage policy and retention period",
[
r"retention period",
r"retention timeframe",
r"how we retain",
r"keep .{0,40}for .{0,30}(?:days|months|years)",
r"no longer than",
r"delete .{0,60}after",
],
[r"retain", r"retained", r"delete", r"deletion"],
),
(
"third-party sharing",
[
r"service providers",
r"third[- ]party service providers",
r"toll operators",
r"payment processors",
r"mapping service providers",
r"sharing your information",
r"we share",
],
[r"partners", r"affiliates"],
),
(
"provider security controls",
[
r"encrypted in transit",
r"encryption",
r"access control",
r"security measures",
r"security measures to safeguard",
],
[r"secure", r"security", r"safeguard"],
),
(
"legal framework named",
[
r"personal data protection act",
r"\bpdpa\b",
r"\bgdpr\b",
r"data protection law",
],
[r"privacy law", r"applicable law"],
),
(
"data-subject rights route",
[
r"delete your account",
r"access to your personal data",
r"data access request",
r"request access to your personal data",
r"right to be forgotten",
],
[r"you can control", r"your choices", r"manage your"],
),
]
HEADERS = {
"User-Agent": "Mozilla/5.0 (compatible; privacy-policy-audit/1.0)",
}
def fetch(url: str) -> str:
req = urllib.request.Request(url, headers=HEADERS)
with urllib.request.urlopen(req, timeout=30) as resp:
raw = resp.read().decode("utf-8", "ignore")
raw = re.sub(r"(?is)<(script|style|nav|footer)\b.*?</\1>", " ", raw)
text = re.sub(r"(?s)<[^>]+>", " ", raw)
text = html.unescape(text)
return re.sub(r"\s+", " ", text).strip()
def score(text: str) -> list[tuple[str, str, str]]:
low = text.lower()
results: list[tuple[str, str, str]] = []
for label, strong, weak in CHECKS:
hit = None
for pattern in strong:
m = re.search(pattern, low)
if m:
hit = m
break
if hit:
snippet = text[max(0, hit.start() - 40) : hit.end() + 90].strip()
results.append((label, "STATED", snippet))
continue
for pattern in weak:
m = re.search(pattern, low)
if m:
snippet = text[max(0, m.start() - 40) : m.end() + 90]
results.append((label, "THIN", snippet.strip()))
break
else:
results.append((label, "UNSTATED", "-"))
return results
def main() -> int:
ap = argparse.ArgumentParser(description=__doc__)
ap.add_argument("url")
ap.add_argument("--save")
args = ap.parse_args()
try:
text = fetch(args.url)
except (urllib.error.URLError, OSError, ValueError) as exc:
print(f"could not read {args.url}: {exc}", file=sys.stderr)
return 2
results = score(text)
stated = sum(1 for _, status, _ in results if status == "STATED")
thin = sum(1 for _, status, _ in results if status == "THIN")
lines = [f"source: {args.url}", f"characters of policy text: {len(text)}", ""]
for label, status, snippet in results:
lines.append(f"[{status:8}] {label}")
if status != "UNSTATED":
lines.append(f" {snippet[:220]}")
lines.append("")
lines.append(f"stated: {stated}/8 thin: {thin}/8 unstated: {8 - stated - thin}/8")
report = "\n".join(lines)
print(report)
if args.save:
with open(args.save, "w", encoding="utf-8") as fh:
fh.write(report + "\n")
return 0
if __name__ == "__main__":
sys.exit(main())
The result:
- TuJu — 4 stated, 2 thin, 2 unstated, across 4,019 characters of policy text.
- Waze — 8 stated, 0 thin, 0 unstated, across more than 46,000 characters.
One caveat before anyone quotes this at a ministry: the audit measures disclosure, not compliance. "Stated" means the policy says something on the topic, and a policy can state everything and still break the law. What it measures is the part a driver can check before installing an app.
The four gaps
1. No retention period, anywhere
The policy never says how long anything is kept. It explains that transaction data is collected "to process your payments and maintain accurate records" and stops there. The Retention Principle in section 10 of the PDPA is specific: personal data "shall not be kept longer than is necessary for the fulfilment of that purpose", and a controller must take reasonable steps to destroy or permanently delete data it no longer needs. For a toll e-wallet that records where you drove and what you paid, "maintain accurate records" is not a limit — it is an open-ended licence.
2. No legal framework, no officer, no breach promise
The policy never mentions the PDPA, a controller registration, a data protection officer or a breach-notification commitment. Since 1 June 2025, section 12a has required every data controller to appoint data protection officers accountable for compliance, and section 12b(1) requires a controller who has reason to believe a breach has occurred to notify the Commissioner "as soon as practicable". Section 12b(2) adds notification to data subjects where the breach "causes or likely to cause any significant harm", and section 12b(3) makes failing to notify the Commissioner an offence: a fine of up to RM250,000, up to two years' imprisonment, or both. A policy silent on all of this says nothing about what happens to your location history on a bad day.
3. "Our mapping service providers" — who, and where?
TuJu's policy says location information "is shared with our mapping service providers to offer navigation services", then adds that "This data is anonymized and aggregated to ensure your privacy". It names no provider, and says nothing about where the data is stored or processed. "Anonymized and aggregated" is asserted without a method or a test.
Waze's policy names its controller as "Waze Mobile Ltd.", "a company incorporated and operating under the laws of Israel", with a Tel Aviv address, and says plainly: "We store data on servers located around the world and your information may be processed on servers located outside of the country where you live."
Section 9(1)(b) of the PDPA makes "the place or location where the personal data is stored" a factor a controller must have regard to when protecting data, and section 129 governs transfers out of Malaysia. TuJu's policy answers neither.
4. No route to act on your data
The "Your Choices" section offers two things: turn off location access through device settings, and review transaction history inside the app. There is no access request, no correction route, no erasure route, and only a general enquiry mailbox for contact. Section 12 of the PDPA gives a data subject access to their personal data and the right to have it corrected, and section 7(1)(d) requires a notice to say how to contact the controller "with any inquiries or complaints". Waze, meanwhile, names an in-app "Delete Account" function and a dedicated privacy mailbox.
The exemption travels with the data
TuJu's own terms, effective 21 September 2026, say: "TuJu is a digital platform operated by Lembaga Lebuhraya Malaysia (LLM) and Prosignal Consortium Sdn. Bhd. (PCSB)". Clause 15 puts the terms under Malaysian law, and its App Store listing calls the app "A Joint Venture between the Malaysian Highway Authority (LLM) and Prosignal Consortium Sdn Bhd (PCSB) since 2022" — a highway authority and a private company, on opposite sides of the PDPA. Local ownership does not decide where the data ends up, as we argued in when governments start building their own digital stack.
Section 3(1) is short: "This Act shall not apply to the Federal Government and State Governments." The Commissioner's applicability guidance repeats that sentence and stops there. It does not extend the exemption to agencies, and it does not say whether a body corporate established by statute counts as "the Federal Government" — neither the Act nor the guidance settles it.
The commercial half is not in doubt. Section 2(1) applies the Act to anyone who processes personal data in respect of commercial transactions, and to anyone who has control over or authorizes the processing of it. TuJu sells toll e-wallet payments, a premium subscription and daily travel insurance — commercial processing, run by Prosignal, so the Act's controller duties land on the private half of the operation, the same duties we walk through in our PDPA guide for developers.
So the flow is: a driver signs in — the app requires an account before navigation — location and movement data reaches Prosignal's commercial stack, bound by the Act on paper, and can from there reach the government partner, whose processing the Act says it does not apply to. Local ownership does not dissolve the exemption. It rides along with the last hop.
And the in-app notice, as reported in the 22 October hands-on review, says the app tracks location, motion and usage behaviour, data which "may be shared with a Malaysian government body". Meanwhile TuJu's App Store listing — a disclosure the developer files with Apple — declares linked data used for "Developer's Advertising or Marketing" and "Third-Party Advertising", including precise location, payment information, phone number, user and device IDs and advertising data. The privacy policy contains no word for advertising. Two first-party disclosures, contradicting each other.
Two housekeeping facts. The privacy policy still carries "Effective Date: 1st September 2023", while the terms that point to it are dated 21 September 2026 and describe a premium subscription and an insurance partnership the 2023 policy never mentions. Every substantive section of the policy is in English only, where section 7(3) requires "the national and English languages". There is no Bahasa Melayu version to read.
What "good enough to recommend" should mean
NACSA's six factors are a usable acceptance test for any navigation app it puts its name behind. Applied to TuJu today, the gaps are fixable in one policy revision:
- Publish a retention schedule per data category, so section 10 has something to point at.
- Name the mapping, cloud and payment providers, and the countries where data is processed.
- Name the data protection officer, and state the breach-notification route and timeline.
- Give an access, correction and erasure channel, plus a complaint path.
- Reconcile the policy with the App Store label and re-date it.
The sixth NACSA factor, security controls, is the one the policy gestures at and then waves away: "We implement security measures to safeguard your information from unauthorized access, loss, or alteration. However, no online service is entirely secure, and we cannot guarantee absolute protection." A disclaimer, not an assurance.
The directive was about jurisdiction; the clause behind it is still worth reading in full. This gap is about disclosure — the cheaper of the two to fix. A Waze user can read where their data goes and who to ask when it goes wrong. A TuJu user, today, cannot.
Sources
- Attorney General's Chambers Malaysia (via Personal Data Protection Department): Personal Data Protection Act 2010 (Act 709) — English reprint as at 15 September 2026
- Personal Data Protection Department: Application and Non-Application of the Act
- National Cyber Security Agency (NACSA): FAQ — Arahan Larangan Penggunan Aplikasi Navigasi Waze bagi Anggota Perkhidmatan Awam
- Prosignal Consortium Sdn Bhd / Lembaga Lebuhraya Malaysia: TuJu — Privacy Policy (Effective Date: 1 September 2023)
- Prosignal Consortium Sdn Bhd / Lembaga Lebuhraya Malaysia: TuJu — Terms and Conditions (Effective Date: 21 September 2026)
- Waze: Waze Privacy Policy (last modified 8 July 2026)
- SoyaCincau: Govt wants Malaysians to ditch Waze for Tuju but the app is barely usable
- Apple: TuJu on the App Store — app privacy details
// author
Editor & Operator
Mohd Firdaus Abu Bakar (MrDodgerX) is an enterprise geospatial systems engineer in Malaysia and the editor behind hejes.my. He runs the briefing pipeline, curates and edits every draft, verifies each factual claim against primary sources, and presses the publish button — nothing ships without his review. He writes about AI, security and Malaysia's tech scene from a builder's perspective. Professional profile and code: the links below.
// sources //
fact-check verified · 22 OCT 2026 · hejes-content-fact-check
- Personal Data Protection Act 2010 (Act 709) — English reprint as at 15 September 2026Attorney General's Chambers Malaysia (via Personal Data Protection Department) · accessed 22 OCT 2026
- Application and Non-Application of the ActPersonal Data Protection Department · accessed 22 OCT 2026
- FAQ — Arahan Larangan Penggunan Aplikasi Navigasi Waze bagi Anggota Perkhidmatan AwamNational Cyber Security Agency (NACSA) · accessed 22 OCT 2026
- TuJu — Privacy Policy (Effective Date: 1 September 2023)Prosignal Consortium Sdn Bhd / Lembaga Lebuhraya Malaysia · accessed 22 OCT 2026
- TuJu — Terms and Conditions (Effective Date: 21 September 2026)Prosignal Consortium Sdn Bhd / Lembaga Lebuhraya Malaysia · accessed 22 OCT 2026
- Waze Privacy Policy (last modified 8 July 2026)Waze · accessed 22 OCT 2026
- Govt wants Malaysians to ditch Waze for Tuju but the app is barely usableSoyaCincau · accessed 22 OCT 2026
- TuJu on the App Store — app privacy detailsApple · accessed 22 OCT 2026
related //

TuJu vs Waze: The Clause Behind PMX's Push
PMX wants Malaysians on TuJu instead of Waze. The Israeli-law clause he cited is real and quotable — here is what it means, and what it does not.

CTOS Breach: When the Credit Agency Asks You to Reset Your Password
CTOS confirmed a limited subset of consumer data was accessed; password-reset notices are now reaching account holders. Here is what it means.

Misi Rakyat Now Acknowledges Cyberattack: What Changed After the Data Leak Analysis?
Misi Rakyat says it was hit by a malicious cyberattack. What the Sep 9 statement confirms, what it leaves open, and how it compares to the Sep 8 leak analysis.
// join the feed
one fresh insight per week. no spam, ever.
weekly digest. unsubscribe anytime.