Hi,
I have so far only used primary key ids everywhere, and this could be a security/privacy concern I'm now learning.
- How do you use primary keys and/or uuid?
- uuid as primary key?
- uuid in frontend/links and id backend/sqls?
- Is there any Trongate related functions, functionality for this?
- Best practice to set a uuid in mysql? (up-to-date version, performance etc.)
Grateful for any tips.
Primary ids, uuid, security
4 months ago
4 months ago
#1
4 months ago
#2
I'm not aware of any specific support/best practices from Trongate or other PHP tools about this.
The most relevant thing I've seen is this video: https://www.youtube.com/watch?v=lopIg_f90MI
He obfuscates the raw table IDs in the output HTML by printing their MD5 hash.
The frontend part is discussed around 13:30 and the backend SQL around 23:30.
The way I'd do it in Trongate would be something like:
In my view:
You'll notice I'm using Trongate MX; that's not related to your question, just the example I had handy.
In my controller:
The most relevant thing I've seen is this video: https://www.youtube.com/watch?v=lopIg_f90MI
He obfuscates the raw table IDs in the output HTML by printing their MD5 hash.
The frontend part is discussed around 13:30 and the backend SQL around 23:30.
The way I'd do it in Trongate would be something like:
In my view:
You'll notice I'm using Trongate MX; that's not related to your question, just the example I had handy.
In my controller:
4 months ago
#3
In general the assumption in Trongate seems to be integer IDs, some methods on Db class assumes int $id but there’s nothing stopping you from using a string ID via query and query_bind method.
- How do you use primary keys and/or uuid?
Refer to MariaDB docs or use like Ramsey/uuid in php
- uuid as primary key?
Sure, call Db::query_bind($sql) or Db::query($sql) directly
- uuid in frontend/links and id backend/sqls?
Doable, I also had a quick glance over Pagination class - it’s easily configured and the actual querying is left to the consuming module. Read Trongate_administrators for sample code.
- Is there any Trongate related functions, functionality for this?
No, not from what I found source diving a bit.
a good contribution may be a uuid helper module.
- Best practice to set a uuid in mysql? (up-to-date version, performance etc.)
Generally I find the most success using recent MariaDB, I’m generally running version 12.3 for my development and servers.
- How do you use primary keys and/or uuid?
Refer to MariaDB docs or use like Ramsey/uuid in php
- uuid as primary key?
Sure, call Db::query_bind($sql) or Db::query($sql) directly
- uuid in frontend/links and id backend/sqls?
Doable, I also had a quick glance over Pagination class - it’s easily configured and the actual querying is left to the consuming module. Read Trongate_administrators for sample code.
- Is there any Trongate related functions, functionality for this?
No, not from what I found source diving a bit.
a good contribution may be a uuid helper module.
- Best practice to set a uuid in mysql? (up-to-date version, performance etc.)
Generally I find the most success using recent MariaDB, I’m generally running version 12.3 for my development and servers.
4 months ago
#4
Hi all,
DC pretty much nailed the spirit of this 👍
There’s a tendency in the wider PHP ecosystem to over-engineer simple problems, and this is a good example. The goal here is not “perfect identifiers” - it’s practical, safe, and maintainable apps.
DC’s point about make_rand_str(32) is spot on:
Simple
Readable
No dependencies
Effectively unguessable
Cleaner than UUIDs in URLs
That aligns very well with the Trongate philosophy: keep things lean, native, and under your control.
That said, I also want to acknowledge the other replies, as they provide useful context.
@sasin91 is absolutely right:
Trongate doesn’t force you into INT IDs
You can use strings / UUIDs via query() / query_bind()
A UUID helper module could be a nice contribution
So yes - you can go full UUID if your project genuinely needs it.
@ak1’s MD5 approach works as a quick obfuscation layer, but it’s worth being clear:
It’s deterministic
It can be brute-forced
It doesn’t really solve the underlying problem
So it’s fine as a lightweight mask, but not something to rely on for security.
Where this all lands (practical Trongate approach):
Keep it simple and split responsibilities:
Use INT id as your primary key (fast, efficient)
Use a random string for public exposure
Example:
Generate it with:
Use it in URLs, query by it in controllers, done.
Important note (this matters more than IDs):
Even with UUIDs, hashes, or random strings:
You MUST still check permissions
You MUST still validate access
Identifiers are not security — they’re just identifiers.
Bottom line
Don’t overcomplicate it
Don’t fight the framework
Don’t import a 10k-line UUID library for a 12-line problem
Trongate gives you what you need out of the box.
Use it, keep it clean, and move on to building something that matters.
Cheers.
PS. Bring back Grady - he/she/ it would have nailed this thread too (AI fan club)
DC pretty much nailed the spirit of this 👍
There’s a tendency in the wider PHP ecosystem to over-engineer simple problems, and this is a good example. The goal here is not “perfect identifiers” - it’s practical, safe, and maintainable apps.
DC’s point about make_rand_str(32) is spot on:
Simple
Readable
No dependencies
Effectively unguessable
Cleaner than UUIDs in URLs
That aligns very well with the Trongate philosophy: keep things lean, native, and under your control.
That said, I also want to acknowledge the other replies, as they provide useful context.
@sasin91 is absolutely right:
Trongate doesn’t force you into INT IDs
You can use strings / UUIDs via query() / query_bind()
A UUID helper module could be a nice contribution
So yes - you can go full UUID if your project genuinely needs it.
@ak1’s MD5 approach works as a quick obfuscation layer, but it’s worth being clear:
It’s deterministic
It can be brute-forced
It doesn’t really solve the underlying problem
So it’s fine as a lightweight mask, but not something to rely on for security.
Where this all lands (practical Trongate approach):
Keep it simple and split responsibilities:
Use INT id as your primary key (fast, efficient)
Use a random string for public exposure
Example:
Generate it with:
Use it in URLs, query by it in controllers, done.
Important note (this matters more than IDs):
Even with UUIDs, hashes, or random strings:
You MUST still check permissions
You MUST still validate access
Identifiers are not security — they’re just identifiers.
Bottom line
Don’t overcomplicate it
Don’t fight the framework
Don’t import a 10k-line UUID library for a 12-line problem
Trongate gives you what you need out of the box.
Use it, keep it clean, and move on to building something that matters.
Cheers.
PS. Bring back Grady - he/she/ it would have nailed this thread too (AI fan club)
4 months ago
#5
Thanks for all the answers!
Then it is clear that public ids should be somewhat masked (make it simple), this is not something I have thought about before lately and also not seen in examples or videos, I feel missing out :)
As a hobby phper I have not got the hang of/understanding of Trongate's Authorization & Authentication yet, but I understand that it is a basis for building a user base and login system.
A login system must often be in place before you get started with what you really wanted to build, but thats another topic maybe.
Thanks again for the responses!
Then it is clear that public ids should be somewhat masked (make it simple), this is not something I have thought about before lately and also not seen in examples or videos, I feel missing out :)
As a hobby phper I have not got the hang of/understanding of Trongate's Authorization & Authentication yet, but I understand that it is a basis for building a user base and login system.
A login system must often be in place before you get started with what you really wanted to build, but thats another topic maybe.
Thanks again for the responses!
4 months ago
#6
Just to jump in with a quick performance tip when hashing strings...
md5 is very long in the tooth and relatively slow for an insecure hashing algo. I prefer to use XXH3 (or XXH128 if you want the same width as md5) introduced in PHP8.1: https://php.watch/versions/8.1/xxHash
Super fast, ultra low collision potential. 31.5 GB/s vs md5's 0.6 GB/s: https://xxhash.com/
Particularly good when working on many small strings, as is often the case when dealing with multiple cache file paths per request.
Also works with hash_file():
md5 is very long in the tooth and relatively slow for an insecure hashing algo. I prefer to use XXH3 (or XXH128 if you want the same width as md5) introduced in PHP8.1: https://php.watch/versions/8.1/xxHash
Super fast, ultra low collision potential. 31.5 GB/s vs md5's 0.6 GB/s: https://xxhash.com/
Particularly good when working on many small strings, as is often the case when dealing with multiple cache file paths per request.
Also works with hash_file():
4 months ago
#7
That’s how simple a UUID v4 generator can be, no library needed.
However good point on make_rand_str(32); - that may just be enough for most cases.
For database indexes, going UUID especially time based ones may be worthwhile.
Internally a UUID can be represented as an integer whereas a string will be compared character by character. :)