
Security News
Open Source Maintainers Demand Ability to Block Copilot-Generated Issues and PRs
Open source maintainers are urging GitHub to let them block Copilot from submitting AI-generated issues and pull requests to their repositories.
github.com/minhajuddin/prefixed_uuids
A Go package that provides a type-safe way to work with prefixed UUIDs. This package allows you to create and parse UUIDs with entity-specific prefixes, making them more readable and ensuring type safety at runtime.
.
, can also use ~
)go get github.com/minhajuddin/prefixed_uuids
First, define your entity types and create a registry:
const (
User Entity = 1
Post Entity = 2
Comment Entity = 3
UserV2 Entity = 5
UserV3 Entity = 6
SessionID Entity = 7
)
registry, err := NewRegistry([]PrefixInfo{
{User, "user"},
{Post, "post"},
{Comment, "comment"},
{UserV2, "user_v2"},
{UserV3, "user_v3"},
{SessionID, "sid"},
})
if err != nil {
// Handle error
}
By default, the registry uses .
as the separator. You can customize this using the fluent interface:
// Use '~' as a separator instead of the default '.'
registry, err = registry.WithSeparator("~")
if err != nil {
// Handle error
}
// This will produce IDs like "user~AZXje_k_dRiprKK-aEY8fg"
Note: Only .
and ~
are allowed as separators since they are not part of the base64url encoding
alphabet and are not encoded in URLs.
uuid := uuid.MustParse("0195e37b-f93f-7518-a9ac-a2be68463c7e")
prefixedUUID := registry.Serialize(User, uuid)
// Result with default separator: "user.AZXje_k_dRiprKK-aEY8fg"
// Result with '~' separator: "user~AZXje_k_dRiprKK-aEY8fg"
// Versioned entities
prefixedUUIDV2 := registry.Serialize(UserV2, uuid)
// Result: "user_v2.AZXje_k_dRiprKK-aEY8fg"
You can parse prefixed UUIDs in two ways:
uuid, err := registry.Deserialize(User, "user.AZXje_k_dRiprKK-aEY8fg")
if err != nil {
// Handle error
}
// uuid.String() == "0195e37b-f93f-7518-a9ac-a2be68463c7e"
entity, uuid, err := registry.DeserializeWithEntity("post.AZXje_k_dRiprKK-aEY8fg")
if err != nil {
// Handle error
}
// entity == Post
// uuid.String() == "0195e37b-f93f-7518-a9ac-a2be68463c7e"
The package returns errors in the following cases:
ErrInvalidPrefixedUUIDFormat
: When the input string doesn't match the expected format (e.g., empty string, no separator)ErrUnknownPrefix
: When the prefix is not registered in the registryErrInvalidUUIDBadBase64
: When the base64 part is invalidErrInvalidUUIDFormat
: When the decoded bytes don't form a valid UUIDErrEntityMismatch
: When the entity type doesn't match the prefixExample error handling:
// Invalid format
_, err := registry.Deserialize(User, "userAZXje_k_dRiprKK-aEY8fg")
// err == ErrInvalidPrefixedUUIDFormat
// Unknown prefix
_, err = registry.Deserialize(User, "unknown.AZXje_k_dRiprKK-aEY8fg")
// err == ErrUnknownPrefix
// Entity mismatch
prefixedUUID := registry.Serialize(User, uuid)
_, err = registry.Deserialize(Post, prefixedUUID)
// err == ErrEntityMismatch
Prefixes must:
^[a-z0-9_-]+$
Invalid prefixes will cause NewRegistry
to return an error:
// These will all return errors:
registry, err := NewRegistry([]PrefixInfo{
{Entity(1), "Test"}, // uppercase
{Entity(1), "test prefix"}, // contains space
{Entity(1), "test@prefix"}, // contains special char
})
The primary use case for this is to convert UUIDs to friendly external IDs when sending it to external systems.
Whenever you show the ID to the outside world, you use a prefixed_uuid and once it gets past your edge code, it is parsed properly.
This way, if you ask a customer for their id and they give you session.AZXje_k_dRiprKK-aEY8fg
instead of user.AZXje_k_dRiprKK-aEY8fg
, you'll know that they gave you the wrong ID. Also, looking at logs, whenever you see an id, you'll know exactly what it is referring to.
Example uses
sid.AZXje_k_dRiprKK-aEY8fg
user.AZXje_k_dRiprKK-aEY8fg
jti.AZXje_k_dRiprKK-aEY8fg
sk_live.AZXje_k_dRiprKK-aEY8fg
sk_test.AZXje_k_dRiprKK-aEY8fg
.
for the separator instead of _
or -
?
_
and -
are part of the alphabet for the base64url encoding scheme that we use to encode the UUID bytes. To make the code more robust, we use a separator that is not part of that alphabet. Also, we don't use :
because it is encoded in urls which is a minor annoyance. The only other separator that can be used other than .
which is not encoded is ~
. You can now use either .
or ~
as separators with the WithSeparator
method.The prefixed UUID format is more compact than the standard UUID format:
uuid := uuid.MustParse("0195e37b-f93f-7518-a9ac-a2be68463c7e")
prefixedUUID := registry.Serialize(User, uuid)
// len(prefixedUUID) == 27 // "user.AZXje_k_dRiprKK-aEY8fg"
// len(uuid.String()) == 36 // "0195e37b-f93f-7518-a9ac-a2be68463c7e"
FAQs
Unknown package
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Open source maintainers are urging GitHub to let them block Copilot from submitting AI-generated issues and pull requests to their repositories.
Research
Security News
Malicious Koishi plugin silently exfiltrates messages with hex strings to a hardcoded QQ account, exposing secrets in chatbots across platforms.
Research
Security News
Malicious PyPI checkers validate stolen emails against TikTok and Instagram APIs, enabling targeted account attacks and dark web credential sales.